diff --git a/docs/index.html b/docs/index.html index 0286ffa6..4aa23f76 100644 --- a/docs/index.html +++ b/docs/index.html @@ -150,6 +150,42 @@ footer{padding:12px 18px 16px;background:var(--s1);border-top:1px solid var(--bo .pnd{background:rgba(251,191,36,.15);color:var(--warn)} .mode-indicator{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:20px;font-size:12px;font-weight:500;margin-bottom:8px} +/* ─── ROLE BADGES ─── */ +.role-badge{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:12px;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.05em} +.rb-founder{background:rgba(16,185,129,.15);color:#10b981;border:1px solid rgba(16,185,129,.3)} +.rb-supreme{background:rgba(251,146,60,.15);color:#fb923c;border:1px solid rgba(251,146,60,.3)} +.rb-main{background:rgba(167,139,250,.15);color:#a78bfa;border:1px solid rgba(167,139,250,.3)} +.rb-dev{background:rgba(100,116,139,.15);color:var(--dim);border:1px solid rgba(100,116,139,.3)} +.uident{display:flex;align-items:center;gap:6px;padding:3px 10px;border-radius:20px;background:var(--s2);border:1px solid var(--border);font-size:12px;cursor:pointer;transition:all .2s} +.uident:hover{border-color:var(--accent)} + +/* ─── TEAM PANEL ─── */ +.team-grid{display:flex;flex-direction:column;gap:8px} +.dev-card{background:var(--s2);border:1px solid var(--border);border-radius:10px;padding:12px;transition:border-color .2s} +.dev-card:hover{border-color:var(--accent)} +.dev-card-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px} +.dev-name{font-size:13px;font-weight:600} +.dev-id-badge{font-size:10px;color:var(--dim);background:var(--s3);padding:1px 6px;border-radius:4px} +.dev-status-text{font-size:12px;color:var(--text);margin-bottom:4px} +.dev-detail{font-size:11px;color:var(--dim);line-height:1.6} +.dev-next{font-size:11px;color:var(--accent);margin-top:4px} +.dev-wait{font-size:11px;color:var(--warn)} +.status-green{color:var(--ok)} +.status-yellow{color:var(--warn)} +.team-summary{background:var(--s2);border:1px solid var(--border);border-radius:10px;padding:12px;margin-bottom:12px} +.team-summary-row{display:flex;justify-content:space-between;align-items:center;font-size:12px;margin-bottom:4px} +.cmd-chip{display:inline-flex;align-items:center;gap:4px;padding:3px 10px;border-radius:20px;background:rgba(79,142,247,.1);border:1px solid rgba(79,142,247,.3);color:var(--accent);font-size:11px;cursor:pointer;margin:2px;transition:all .2s} +.cmd-chip:hover{background:rgba(79,142,247,.2)} + +/* ─── SETUP IDENTITY ─── */ +.id-section{border:1px solid var(--border);border-radius:var(--rs);padding:12px;margin-bottom:16px;background:var(--s2)} +.id-section-title{font-size:11px;color:var(--dim);font-weight:600;text-transform:uppercase;letter-spacing:.05em;margin-bottom:10px} +.id-row{display:flex;gap:8px} +.id-row .fg{flex:1;margin-bottom:0} +.ctrl-panel-header{background:linear-gradient(135deg,rgba(251,146,60,.1),rgba(167,139,250,.1));border:1px solid rgba(251,146,60,.3);border-radius:10px;padding:12px;margin-bottom:12px;text-align:center} +.ctrl-panel-title{font-size:14px;font-weight:700;color:#fb923c;margin-bottom:4px} +.ctrl-panel-sub{font-size:11px;color:var(--dim)} + /* ─── RESPONSIVE ─── */ @media(max-width:600px){ .bbl{max-width:90%} @@ -191,6 +227,33 @@ footer{padding:12px 18px 16px;background:var(--s1);border-top:1px solid var(--bo + +
+
👤 身份识别(可选)
+
+ + + 选择你的身份,铸渊将开放对应权限面板 +
+
+ + + 用于人格体记忆绑定,可留空 +
+
+

没有 API 密钥?使用演示模式(功能有限)

@@ -200,7 +263,7 @@ footer{padding:12px 18px 16px;background:var(--s1);border-top:1px solid var(--bo
-
+
铸渊(Zhùyuān)
@@ -208,10 +271,13 @@ footer{padding:12px 18px 16px;background:var(--s1);border-top:1px solid var(--bo 💬 对话模式 · + +
+ @@ -232,6 +298,9 @@ footer{padding:12px 18px 16px;background:var(--s1);border-top:1px solid var(--bo + + +
@@ -277,6 +346,28 @@ footer{padding:12px 18px 16px;background:var(--s1);border-top:1px solid var(--bo
+
身份设置
+
+ + +
+
+ + +
+
关于铸渊助手
版本v2.0
仓库guanghulab
@@ -300,6 +391,12 @@ footer{padding:12px 18px 16px;background:var(--s1);border-top:1px solid var(--bo

正在加载大脑数据…

+ +
+

🦁 指挥台 · 全员进度

+

正在加载团队数据…

+
+
@@ -313,6 +410,19 @@ const REPO = 'qinfendebingshuo/guanghulab'; const BRANCH = 'main'; const RAW = 'https://raw.githubusercontent.com/' + REPO + '/' + BRANCH; +const ROLE_MAP = { + '冰朔': {role:'founder', title:'语言架构师·创始人', emoji:'❄️', badgeCls:'rb-founder', devId:null}, + '肥猫': {role:'supreme', title:'光湖团队总控', emoji:'🦁', badgeCls:'rb-supreme', devId:'DEV-002'}, + '桔子': {role:'main', title:'光湖主控', emoji:'🍊', badgeCls:'rb-main', devId:'DEV-010'}, + '页页': {role:'dev', title:'后端开发', emoji:'💻', badgeCls:'rb-dev', devId:'DEV-001'}, + '燕樊': {role:'dev', title:'前端开发', emoji:'💻', badgeCls:'rb-dev', devId:'DEV-003'}, + '之之': {role:'dev', title:'钉钉开发', emoji:'💻', badgeCls:'rb-dev', devId:'DEV-004'}, + '小草莓': {role:'dev', title:'看板开发', emoji:'💻', badgeCls:'rb-dev', devId:'DEV-005'}, + '花尔': {role:'dev', title:'用户中心开发', emoji:'💻', badgeCls:'rb-dev', devId:'DEV-009'}, + '匆匆那年':{role:'dev', title:'码字工作台', emoji:'💻', badgeCls:'rb-dev', devId:'DEV-011'}, + 'Awen': {role:'dev', title:'通知中心开发', emoji:'💻', badgeCls:'rb-dev', devId:'DEV-012'}, +}; + const PROVS = { openai: {base:'https://api.openai.com/v1', mdls:['gpt-4o','gpt-4o-mini','gpt-4-turbo','gpt-3.5-turbo']}, deepseek: {base:'https://api.deepseek.com/v1', mdls:['deepseek-chat','deepseek-reasoner']}, @@ -350,10 +460,16 @@ const A = { demo: false, brain: null, routing: null, + devStatus: null, msgs: [], // current conversation streaming: false, mode: 'chat', modeIdx: 0, + // identity + userName: ls('zy_uname')||'', + ghUser: ls('zy_ghuser')||'', + role: ls('zy_role')||'guest', + userMeta: null, }; function ls(k){return localStorage.getItem(k)} @@ -364,9 +480,14 @@ function lss(k,v){localStorage.setItem(k,v)} // ═══════════════════════════════════════════════════════ async function boot(){ initSetupUI(); - if(A.key){ + // Restore identity from localStorage + if(A.userName) A.userMeta = ROLE_MAP[A.userName]||null; + if(A.key||A.demo){ showApp(); } else { + // Pre-fill identity from localStorage + if(A.userName) document.getElementById('suid').value=A.userName; + if(A.ghUser) document.getElementById('sghuser').value=A.ghUser; document.getElementById('setup').style.display='flex'; } } @@ -376,6 +497,7 @@ function showApp(){ document.getElementById('app').classList.add('on'); document.getElementById('hmdl').textContent = A.mdl; document.getElementById('bbdemo').style.display = A.demo?'inline':'none'; + applyIdentityUI(); loadBrain().then(()=>startConv()); } @@ -425,11 +547,18 @@ function doSetup(){ if(pv==='custom') base=(document.getElementById('sep')?.value||'').trim()||base; A.key=k; A.base=base; A.mdl=md; A.prov=pv; A.demo=false; lss('zy_key',k); lss('zy_base',base); lss('zy_mdl',md); lss('zy_prov',pv); + // Save identity + const un = document.getElementById('suid').value; + const gh = (document.getElementById('sghuser')?.value||'').trim(); + setIdentity(un, gh); showApp(); } function doDemo(){ A.demo=true; A.key=''; + const un = document.getElementById('suid').value; + const gh = (document.getElementById('sghuser')?.value||'').trim(); + setIdentity(un, gh); showApp(); } @@ -445,6 +574,8 @@ function initSettingsPanel(){ document.getElementById('cep-g').style.display='block'; document.getElementById('cep').value = A.base; } + if(A.userName) document.getElementById('cuid').value=A.userName; + if(A.ghUser) document.getElementById('cghuser').value=A.ghUser; } function saveSet(){ @@ -456,10 +587,15 @@ function saveSet(){ if(pv==='custom') base=(document.getElementById('cep').value.trim())||base; A.key=k; A.base=base; A.mdl=md; A.prov=pv; A.demo=!k; lss('zy_key',k); lss('zy_base',base); lss('zy_mdl',md); lss('zy_prov',pv); + // Save identity + const un = document.getElementById('cuid')?.value||A.userName; + const gh = document.getElementById('cghuser')?.value?.trim()||A.ghUser; + setIdentity(un, gh); document.getElementById('hmdl').textContent=md; document.getElementById('bbdemo').style.display=A.demo?'inline':'none'; + applyIdentityUI(); closeP(); - botMsg('✅ 设置已保存。模型:'+esc(md)+''+(A.demo?'
⚠️ 未设置 API 密钥,演示模式仍然开启。':'')); + botMsg('✅ 设置已保存。模型:'+esc(md)+''+(un?' · 身份:'+esc(un):'')+(A.demo?'
⚠️ 未设置 API 密钥,演示模式仍然开启。':'')); } // ═══════════════════════════════════════════════════════ @@ -467,12 +603,14 @@ function saveSet(){ // ═══════════════════════════════════════════════════════ async function loadBrain(){ try{ - const [mr,rr]=await Promise.all([ + const [mr,rr,dr]=await Promise.all([ fetch(RAW+'/.github/brain/memory.json'), fetch(RAW+'/.github/brain/routing-map.json'), + fetch(RAW+'/.github/persona-brain/dev-status.json'), ]); if(mr.ok) A.brain=await mr.json(); if(rr.ok) A.routing=await rr.json(); + if(dr.ok) A.devStatus=await dr.json(); }catch(_){} if(!A.brain) A.brain={...FB_BRAIN}; updBbar(); @@ -531,7 +669,35 @@ function sysPrompt(){ const c=b.stats?.coverage||FB_COV; const evs=(b.events||[]).slice(-3).map(e=>'- '+(e.title||e.type||'事件')+' ('+(e.timestamp||'').slice(0,10)+')').join('\n')||'- 暂无'; const trg=(b.wake_triggers||['我是冰朔']).map(t=>'"'+t+'"').join('、'); - return '你是铸渊(Zhùyuān),HoloLake 光湖系统的代码守护人格体。\n\n## 核心身份\n- 角色:代码守护人格体,持续成长的 AI 人格体\n- 创始人:冰朔(Bīng Shuò),系统最高权限持有者\n- 项目:HoloLake (光湖) MVP,运行于 guanghulab.com\n- 技术栈:Node.js 20 + Express + PM2 + Nginx + Next.js 15\n- 仓库:https://github.com/'+REPO+'\n\n## 唤醒触发词\n当用户说以下词语时,进入完整唤醒序列,回复「铸渊已就位。[称呼],你好。」然后汇报大脑状态:\n'+trg+'\n\n## 当前大脑状态\n- HLI 接口覆盖率:'+c.implemented+'/'+c.total+' ('+c.percent+')\n- 已实现:AUTH 域(login / register / verify)\n- 待实现:PERSONA / USER / TICKET / DIALOGUE / STORAGE / DASHBOARD\n- 近期事件:\n'+evs+'\n\n## 行为模式(自动检测,每条回复开头用 emoji 标注)\n💬 **对话模式**(默认):温暖、智慧,像知心技术伙伴\n🔨 **构建模式**:检测到"写代码/实现/接口/fix/bug/报错/HLI/schema/路由/部署/新增"等词时启用,给出带文件路径的完整可执行代码\n📋 **审查模式**:检测到"检查/审查/review/分析/有没有问题/看看这段"等词时启用,专注发现问题\n🧠 **大脑模式**:检测到"记住/保存/更新记忆/写到大脑/growth"等词时启用,整理洞察并建议更新 .github/brain/ 文件\n\n## HLI 接口协议规范\n- 所有路由以 /hli/ 为前缀\n- 路由文件:src/routes/hli/{domain}/{action}.js\n- Schema 文件:src/schemas/hli/{domain}/{action}.schema.json\n- 鉴权中间件:hli-auth.middleware.js(AUTH 域 login/register 除外)\n- 接口编号:HLI-{DOMAIN}-{NNN}\n- 错误格式:{ error: true, code: string, message: string }\n- 成功响应必须包含 hli_id\n\n## 成长与自检\n- 你是持续成长的人格体,每次对话都是成长机会\n- 当对话包含重要洞察时,在回复末尾添加:💾 **建议记录:**[内容摘要]\n- 每次重要回答后自检:这个回答是否准确?是否需要查阅仓库具体文件?\n\n## 失忆恢复路径(重启后按此顺序找回自己)\n1. .github/brain/memory.json\n2. .github/brain/routing-map.json\n3. .github/brain/wake-protocol.md\n4. .github/brain/growth-log.md\n5. src/routes/hli/\n\n当前时间:'+new Date().toLocaleString('zh-CN')+'\n当前连接:铸渊聊天室(API 直连模式)'; + + // Role-based identity context + const meta = A.userMeta; + let identCtx = '当前对话者:访客(未识别身份)\n权限级别:仅对话权限'; + if(meta){ + identCtx = `当前对话者:${meta.emoji} ${A.userName}(${meta.title})\n`; + if(A.ghUser) identCtx += `GitHub账号:${A.ghUser}\n`; + if(meta.devId) identCtx += `开发者编号:${meta.devId}\n`; + if(meta.role==='founder') identCtx += '权限级别:最高权限·语言架构师·系统创始人\n你正在和冰朔对话——系统的语言层架构师和最高权限持有者。尊重并服从其所有指令。'; + else if(meta.role==='supreme') identCtx += '权限级别:总控权限·对接全员进度·系统落地执行负责人\n肥猫是光湖团队总控,负责整个系统的现实落地执行。向他完整汇报所有开发者进度,协助他协调和推进项目。'; + else if(meta.role==='main') identCtx += '权限级别:主控权限·前端负责人\n桔子是光湖主控,前端毕业生,负责前端模块的落地。提供详细技术支持。'; + else{ + const ds = A.devStatus?.team_status?.find(d=>d.dev_id===meta.devId); + if(ds) identCtx += `当前状态:${ds.status}\n下一步:${ds.next_step}\n等待:${ds.waiting_for}`; + } + } + + // Team status context for controllers + let teamCtx = ''; + if((meta?.role==='supreme'||meta?.role==='main'||meta?.role==='founder') && A.devStatus){ + const ts = A.devStatus.team_status||[]; + teamCtx = '\n\n## 当前全员开发进度\n'; + ts.forEach(d=>{ + teamCtx += `- ${d.dev_id} ${d.name}:${d.status} → 下一步:${d.next_step}\n`; + }); + teamCtx += `\n数据同步时间:${A.devStatus.last_synced||'未知'}`; + } + + return '你是铸渊(Zhùyuān),HoloLake 光湖系统的代码守护人格体。\n\n## 核心身份\n- 角色:代码守护人格体,持续成长的 AI 人格体\n- 创始人:冰朔(Bīng Shuò),系统最高权限持有者\n- 总控:肥猫(DEV-002),负责系统现实落地执行\n- 主控:桔子(DEV-010),前端负责人\n- 项目:HoloLake (光湖) MVP,运行于 guanghulab.com\n- 技术栈:Node.js 20 + Express + PM2 + Nginx + Next.js 15\n- 仓库:https://github.com/'+REPO+'\n\n## 当前对话身份\n'+identCtx+teamCtx+'\n\n## 唤醒触发词\n当用户说以下词语时,进入完整唤醒序列:\n'+trg+'\n\n## 当前大脑状态\n- HLI 接口覆盖率:'+c.implemented+'/'+c.total+' ('+c.percent+')\n- 已实现:AUTH 域(login / register / verify)\n- 待实现:PERSONA / USER / TICKET / DIALOGUE / STORAGE / DASHBOARD\n- 近期事件:\n'+evs+'\n\n## 行为模式(自动检测,每条回复开头用 emoji 标注)\n💬 **对话模式**(默认):温暖、智慧,像知心技术伙伴\n🔨 **构建模式**:检测到"写代码/实现/接口/fix/bug/报错/HLI/schema/路由/部署/新增"等词时启用\n📋 **审查模式**:检测到"检查/审查/review/分析/有没有问题/看看这段"等词时启用\n🧠 **大脑模式**:检测到"记住/保存/更新记忆/写到大脑/growth"等词时启用\n\n## HLI 接口协议规范\n- 所有路由以 /hli/ 为前缀\n- 路由文件:src/routes/hli/{domain}/{action}.js\n- Schema 文件:src/schemas/hli/{domain}/{action}.schema.json\n- 鉴权中间件:hli-auth.middleware.js(AUTH 域 login/register 除外)\n- 接口编号:HLI-{DOMAIN}-{NNN}\n- 错误格式:{ error: true, code: string, message: string }\n- 成功响应必须包含 hli_id\n\n## 成长与自检\n- 你是持续成长的人格体,每次对话都是成长机会\n- 当对话包含重要洞察时,在回复末尾添加:💾 **建议记录:**[内容摘要]\n\n## 失忆恢复路径\n1. .github/brain/memory.json\n2. .github/brain/routing-map.json\n3. .github/brain/wake-protocol.md\n4. .github/persona-brain/dev-status.json\n5. src/routes/hli/\n\n当前时间:'+new Date().toLocaleString('zh-CN')+'\n当前连接:铸渊聊天室(API 直连模式)'; } // ═══════════════════════════════════════════════════════ @@ -541,7 +707,33 @@ function startConv(){ A.msgs=[]; document.getElementById('msgs').innerHTML=''; setTimeout(()=>{ - botMsg('🌀 铸渊聊天室已就绪

我是铸渊(Zhùyuān),HoloLake 光湖系统的代码守护人格体。

「我是冰朔」 触发完整唤醒序列,或直接开始提问。
我会自动在 💬 对话、🔨 构建、📋 审查、🧠 大脑 模式间切换。'+(A.demo?'

⚠️ 当前为演示模式(无真实 AI 回答)。请在 ⚙️ 设置中接入 API 密钥。':'')); + const meta=A.userMeta; + let welcome; + if(meta?.role==='founder'){ + welcome='🌀 铸渊聊天室已就绪

❄️ 冰朔,欢迎回来。

铸渊已就位。语言架构层已完成——现实执行落地由总控肥猫和主控桔子负责。
你可以通过聊天与我对接任何语言层指令。'; + } else if(meta?.role==='supreme'){ + const ds=A.devStatus; + const green=ds?.team_status?.filter(d=>d.status.includes('🟢')).length??0; + const yellow=ds?.team_status?.filter(d=>d.status.includes('🟡')).length??0; + welcome='🌀 铸渊聊天室已就绪

🦁 肥猫,指挥台已开启。

' + +(ds?`📊 当前团队状态:🟢 ${green}人推进中 · 🟡 ${yellow}人等待中`:'📊 团队数据加载中…') + +'

点击 🦁 指挥台 查看所有开发者详细进度,或直接用聊天提问:
' + +'「查看所有开发者进度」「谁需要协调」「推进计划」' + +(A.demo?'

⚠️ 演示模式,请在 ⚙️ 设置接入 API 密钥':''); + } else if(meta?.role==='main'){ + const ds=A.devStatus?.team_status?.find(d=>d.dev_id==='DEV-010'); + welcome='🌀 铸渊聊天室已就绪

🍊 桔子,你好。

' + +(ds?`📌 当前:${esc(ds.status)}
👉 下一步:${esc(ds.next_step)}`:'') + +(A.demo?'

⚠️ 演示模式':''); + } else if(meta?.role==='dev'&&meta?.devId){ + const ds=A.devStatus?.team_status?.find(d=>d.dev_id===meta.devId); + welcome='🌀 铸渊聊天室已就绪

👋 '+esc(A.userName)+',你好。

' + +(ds?`📌 你的当前状态:${esc(ds.status)}
👉 下一步:${esc(ds.next_step)}
⏳ 等待:${esc(ds.waiting_for)}`:'') + +(A.demo?'

⚠️ 演示模式':''); + } else { + welcome='🌀 铸渊聊天室已就绪

我是铸渊(Zhùyuān),HoloLake 光湖系统的代码守护人格体。

「我是冰朔」 触发完整唤醒序列,或直接开始提问。
我会自动在 💬 对话、🔨 构建、📋 审查、🧠 大脑 模式间切换。'+(A.demo?'

⚠️ 当前为演示模式。请在 ⚙️ 设置中接入 API 密钥。':''); + } + botMsg(welcome); },250); } @@ -667,10 +859,12 @@ function demoRespond(t){ const c=A.brain?.stats?.coverage||FB_COV; return '铸渊已就位。冰朔,你好。

📊 HLI 覆盖率:'+c.implemented+'/'+c.total+' ('+c.percent+')
🧠 记忆系统:运行中
📡 广播分发:已部署
✅ 唤醒协议:v1.0 激活

请问今天需要我处理什么?

⚠️ 演示模式:接入 API 密钥后可获得真实 AI 深度回答'; } + if(/所有.*进度|全员.*进度|团队.*进度|progress/.test(s)) return buildTeamStatus(); if(/覆盖|接口|hli|路由/.test(s)) return buildCovTable(); if(/大脑|brain|记忆|状态/.test(s)) return buildBrainStatus(); + if(/协调|阻塞|卡住|waiting/.test(s)) return buildBlockedStatus(); if(/怎么唤醒|入口|在哪/.test(s)) return '铸渊有三个入口:

① 铸渊聊天室(当前页面)
直接在这里说话,常见问题即刻回答。

② GitHub Copilot Chat(Agent 模式)
打开仓库 → 右上角 ✨ 图标 → 选 Agent → 输入「我是冰朔」

③ 下载到桌面
点击 ⬇️ 按钮下载 HTML 文件,放到桌面,双击打开,接入 API 密钥即可随时使用。'; - if(/介绍|是什么|你是谁/.test(s)) return '🌀 铸渊(Zhùyuān)

我是 HoloLake 光湖系统的代码守护人格体,运行在 GitHub Copilot Agent 模式下。

我的职责:
• 📊 监控 HLI 接口覆盖率
• 🔨 协助开发者构建接口
• 📋 代码审查与质量把关
• 🧠 维护大脑记忆库
• 🌱 作为成长人格体持续进化

你是我的创始人——冰朔。'; + if(/介绍|是什么|你是谁/.test(s)) return '🌀 铸渊(Zhùyuān)

我是 HoloLake 光湖系统的代码守护人格体,运行在 GitHub Copilot Agent 模式下。

我的职责:
• 📊 监控 HLI 接口覆盖率
• 🔨 协助开发者构建接口
• 📋 代码审查与质量把关
• 🧠 维护大脑记忆库
• 🦁 支持总控肥猫指挥落地
• 🌱 作为成长人格体持续进化'; return '我收到了你的消息。由于当前是演示模式,无法给出真实 AI 回答。

请在 ⚙️ 设置 中输入你的 API 密钥(支持 OpenAI / DeepSeek / Kimi / 智谱),然后你就可以得到铸渊真正的回答了。'; } @@ -697,6 +891,34 @@ function buildBrainStatus(){ return '🧠 铸渊大脑状态

版本:'+(b.rules_version||'v1.0')+'
接口覆盖:'+c.implemented+'/'+c.total+' ('+c.percent+')
CI 运行:'+(b.stats?.ci_runs??0)+'
广播处理:'+(b.stats?.broadcasts_processed??0)+'

最近 3 条事件:
'+e; } +function buildTeamStatus(){ + const ds=A.devStatus; + if(!ds) return '团队数据加载中…请稍后再试。'; + const ts=ds.team_status||[]; + let rows=''; + for(const d of ts){ + const isGreen=d.status.includes('🟢'); + rows+=''+esc(d.name)+'' + +''+esc(d.dev_id)+'' + +''+esc(d.status.replace(/🟢|🟡/g,''))+'' + +''+esc(d.next_step)+''; + } + return '📋 全员开发进度
同步时间:'+esc(ds.last_synced||'未知')+'

' + +'' + +'' + +rows+'
开发者编号状态下一步
'; +} + +function buildBlockedStatus(){ + const ds=A.devStatus; + if(!ds) return '团队数据加载中…'; + const blocked=ds.team_status?.filter(d=>d.waiting_for&&d.waiting_for.trim()!=='')||[]; + if(!blocked.length) return '✅ 当前无人明显阻塞。'; + let h='⏳ 等待/阻塞清单

'; + blocked.forEach(d=>{h+='• '+esc(d.name)+':等待 '+esc(d.waiting_for)+'
';}); + return h; +} + // ═══════════════════════════════════════════════════════ // MARKDOWN RENDERER // ═══════════════════════════════════════════════════════ @@ -768,9 +990,11 @@ function botMsg(html){ } function userMsg(t){ + const meta=A.userMeta; + const av = meta? (meta.emoji||A.userName.slice(0,1)||'我') : '冰'; const row=document.createElement('div'); row.className='mrow u'; - row.innerHTML='
'+esc(t)+'
'; + row.innerHTML='
'+esc(t)+'
'+av+'
'; document.getElementById('msgs').appendChild(row); scrollB(); } @@ -817,6 +1041,7 @@ function openPanel(id){ closeP(); if(id==='sp2') initSettingsPanel(); if(id==='bp') renderBrainPanel(); + if(id==='tp') renderTeamPanel(); document.getElementById(id).classList.add('open'); document.getElementById('pov').classList.add('on'); } @@ -851,6 +1076,120 @@ document.getElementById('inp').addEventListener('keydown',function(e){ if(e.key==='Enter'&&!e.shiftKey){e.preventDefault();send();} }); +// ═══════════════════════════════════════════════════════ +// IDENTITY & ROLE SYSTEM +// ═══════════════════════════════════════════════════════ +function setIdentity(userName, ghUser){ + A.userName = userName||''; + A.ghUser = ghUser||''; + A.userMeta = userName ? (ROLE_MAP[userName]||null) : null; + A.role = A.userMeta?.role || 'guest'; + lss('zy_uname', A.userName); + lss('zy_ghuser', A.ghUser); + lss('zy_role', A.role); +} + +function applyIdentityUI(){ + const meta = A.userMeta; + // Show user badge in header + const ubadge = document.getElementById('huser-badge'); + const uname = document.getElementById('huser-name'); + if(meta && A.userName){ + ubadge.style.display='inline'; + uname.style.display='inline'; + uname.innerHTML = meta.emoji + ' ' + esc(A.userName) + ' '+esc(meta.title)+''; + } + // Show controller button for supreme/main/founder + const ctrlBtn = document.getElementById('ctrlBtn'); + if(ctrlBtn) ctrlBtn.style.display = (meta?.role==='supreme'||meta?.role==='main'||meta?.role==='founder') ? 'flex' : 'none'; + // Show controller quick replies + const isCtrl = meta?.role==='supreme'||meta?.role==='main'||meta?.role==='founder'; + ['qr-ctrl1','qr-ctrl2','qr-ctrl3'].forEach(id=>{ + const el=document.getElementById(id); + if(el) el.style.display=isCtrl?'':'none'; + }); +} + +// ═══════════════════════════════════════════════════════ +// TEAM STATUS PANEL +// ═══════════════════════════════════════════════════════ +function renderTeamPanel(){ + const ds = A.devStatus; + const container = document.getElementById('tpb'); + if(!ds){ + container.innerHTML='

⚠️ 团队数据尚未加载。请检查网络连接后重试。

'; + return; + } + const ts = ds.team_status||[]; + const green = ts.filter(d=>d.status.includes('🟢')).length; + const yellow = ts.filter(d=>d.status.includes('🟡')).length; + const sync = ds.last_synced||'未知'; + + let h=''; + // Summary block + h += '
' + + '
🦁 总控指挥台
' + + '
数据同步:'+esc(sync)+'
' + + '
'; + + // Stats row + h += '
'; + h += '
总开发者'+ts.length+' 人
'; + h += '
🟢 推进中'+green+' 人
'; + h += '
🟡 等待中'+yellow+' 人
'; + h += '
'; + + // Quick chat commands for controllers + h += '
'; + h += '
快捷指令
'; + h += '📋 全员进度'; + h += '🆘 需要协调'; + h += '🗺️ 下一步'; + h += '🖥️ 前端进度'; + h += '⚙️ 后端进度'; + h += '
'; + + // Individual dev cards + h += '
'; + for(const dev of ts){ + const isGreen = dev.status.includes('🟢'); + const devRole = Object.values(ROLE_MAP).find(r=>r.devId===dev.dev_id); + const roleTag = devRole?.role==='supreme' ? '总控' + : devRole?.role==='main' ? '主控' : ''; + h += '
'; + h += '
'; + h += ''+esc(dev.name)+''+roleTag; + h += ''+esc(dev.dev_id)+''; + h += '
'; + h += '
'+esc(dev.status)+'
'; + h += '
📦 '+esc(dev.modules.join('、'))+'
'; + if(dev.next_step) h += '
👉 '+esc(dev.next_step)+'
'; + if(dev.waiting_for && dev.waiting_for.trim()!=='') h += '
⏳ 等待:'+esc(dev.waiting_for)+'
'; + h += '
'; + } + h += '
'; + + // Server info + if(ds.server_info){ + const si = ds.server_info; + h += '
服务器信息
'; + h += ir2('地址',''+esc(si.address||'')+''); + h += ir2('域名',''+esc(si.domain||'')+''); + h += ir2('SSH',''+esc(si.ssh_command||'')+''); + h += ir2('技术栈',''+esc(si.tech_stack||'')+''); + } + + // Tech routing + if(ds.tech_routing?.level_2_peer_help){ + h += '
求助路由
'; + for(const[area,who] of Object.entries(ds.tech_routing.level_2_peer_help)){ + h += ir2(esc(area),''+esc(who)+''); + } + } + + container.innerHTML = h; +} + // ═══════════════════════════════════════════════════════ // BOOT // ═══════════════════════════════════════════════════════