From f970188776e19f0a1fc544bdacc87e7a221d26d7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Mar 2026 07:50:53 +0000 Subject: [PATCH] fix: make Persona Studio accessible via GitHub Pages and update broken links - Copy persona-studio frontend to docs/persona-studio/ for GitHub Pages deployment - Update API base URL to point to guanghulab.com production server - Update all README links from broken guanghulab.com/persona-studio/ to GitHub Pages URL - Update deploy-pages.yml to trigger on persona-studio/frontend changes and sync files - Update persona-studio/README.md link to point to guanghulab repo Pages Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com> --- .github/workflows/deploy-pages.yml | 6 + README.md | 6 +- docs/persona-studio/chat.html | 63 ++++ docs/persona-studio/chat.js | 205 ++++++++++++ docs/persona-studio/index.html | 141 +++++++++ docs/persona-studio/style.css | 491 +++++++++++++++++++++++++++++ persona-studio/README.md | 2 +- persona-studio/frontend/chat.js | 2 +- persona-studio/frontend/index.html | 2 +- 9 files changed, 912 insertions(+), 6 deletions(-) create mode 100644 docs/persona-studio/chat.html create mode 100644 docs/persona-studio/chat.js create mode 100644 docs/persona-studio/index.html create mode 100644 docs/persona-studio/style.css diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml index 1c46c414..25703f72 100644 --- a/.github/workflows/deploy-pages.yml +++ b/.github/workflows/deploy-pages.yml @@ -6,6 +6,7 @@ on: - main # 仅 main 分支触发生产部署 paths: - 'docs/**' + - 'persona-studio/frontend/**' - '.github/brain/**' workflow_dispatch: @@ -31,6 +32,11 @@ jobs: - name: Setup Pages uses: actions/configure-pages@v5 + - name: Sync Persona Studio frontend to docs + run: | + mkdir -p docs/persona-studio + cp -r persona-studio/frontend/* docs/persona-studio/ + - name: Upload Pages artifact uses: actions/upload-pages-artifact@v3 with: diff --git a/README.md b/README.md index 526d05b0..b916051a 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@
-### 🚀 [点击进入 Persona Studio →](https://guanghulab.com/persona-studio/) +### 🚀 [点击进入 Persona Studio →](https://qinfendebingshuo.github.io/guanghulab/persona-studio/) 💬 自然语言对话  ·  🧠 智能代码生成  ·  📧 邮件推送结果  ·  🔄 对话记忆 @@ -59,7 +59,7 @@ | **铸渊 Zhùyuān** | 代码守护者 | 代码审查、CI 巡检、模块协议执行、Issue 回复 | | **冰朔 Bīng Shuò** | 系统创建者 | 系统架构设计、核心决策、广播发布 | | **霜砚 Shuāng Yàn** | 人格导师 | 人格调校、风格管理、联觉语言系统 | -| **知秋 Zhī Qiū** | 协助开发者 | 对话协助、代码生成、开发体验([Persona Studio](https://guanghulab.com/persona-studio/)) | +| **知秋 Zhī Qiū** | 协助开发者 | 对话协助、代码生成、开发体验([Persona Studio](https://qinfendebingshuo.github.io/guanghulab/persona-studio/)) | --- @@ -213,7 +213,7 @@ ### 体验模块 | 模块 | 说明 | |------|------| -| `persona-studio/` | 人格体协助开发体验([进入 →](https://guanghulab.com/persona-studio/)) | +| `persona-studio/` | 人格体协助开发体验([进入 →](https://qinfendebingshuo.github.io/guanghulab/persona-studio/)) | ### 系统支撑 | 模块 | 说明 | diff --git a/docs/persona-studio/chat.html b/docs/persona-studio/chat.html new file mode 100644 index 00000000..9b484d98 --- /dev/null +++ b/docs/persona-studio/chat.html @@ -0,0 +1,63 @@ + + + + + + 知秋 · 对话 + + + +
+
+
+ 🧠 知秋 + 光湖系统·开发协助人格体 +
+
+ + +
+
+ +
+ +
+ +
+
+ + +
+
+ +
+
+
+ + + + + + + diff --git a/docs/persona-studio/chat.js b/docs/persona-studio/chat.js new file mode 100644 index 00000000..4fcf88ef --- /dev/null +++ b/docs/persona-studio/chat.js @@ -0,0 +1,205 @@ +/* ======================================== + Persona Studio · Chat Logic + ======================================== */ + +const DEV_ID = sessionStorage.getItem('dev_id'); +const SESSION_TOKEN = sessionStorage.getItem('session_token'); + +const API_BASE = (function () { + if (location.hostname === 'localhost' || location.hostname === '127.0.0.1') { + return 'http://localhost:3002'; + } + return 'https://guanghulab.com'; +})(); + +/* ---- Init ---- */ +(function init() { + if (!DEV_ID) { + window.location.href = 'index.html'; + return; + } + + document.getElementById('devIdDisplay').textContent = DEV_ID; + loadHistory(); +})(); + +/* ---- State ---- */ +let conversationHistory = []; +let buildReady = false; + +/* ---- Load History ---- */ +async function loadHistory() { + try { + const res = await fetch(API_BASE + '/api/ps/chat/history?dev_id=' + encodeURIComponent(DEV_ID), { + headers: authHeaders() + }); + if (res.ok) { + const data = await res.json(); + if (data.conversations && data.conversations.length > 0) { + conversationHistory = data.conversations; + data.conversations.forEach(function (msg) { + appendMessage(msg.role === 'user' ? 'user' : 'persona', msg.content); + }); + } + } + } catch (_err) { + // History load failed silently — greeting will come from first message + } + + if (conversationHistory.length === 0) { + sendGreeting(); + } +} + +/* ---- Greeting ---- */ +async function sendGreeting() { + try { + const res = await fetch(API_BASE + '/api/ps/chat/message', { + method: 'POST', + headers: authHeaders({ 'Content-Type': 'application/json' }), + body: JSON.stringify({ dev_id: DEV_ID, message: '__greeting__' }) + }); + const data = await res.json(); + if (data.reply) { + appendMessage('persona', data.reply); + conversationHistory.push({ role: 'assistant', content: data.reply }); + } + } catch (_err) { + appendMessage('persona', '你好!我是知秋,光湖系统的开发协助人格体。告诉我你想做什么,我们一起聊聊方案,聊好了我来帮你开发。'); + } +} + +/* ---- Send Message ---- */ +async function sendMessage() { + var input = document.getElementById('msgInput'); + var text = input.value.trim(); + if (!text) return; + + input.value = ''; + autoResizeTextarea(input); + appendMessage('user', text); + conversationHistory.push({ role: 'user', content: text }); + + var sendBtn = document.getElementById('sendBtn'); + sendBtn.disabled = true; + + try { + var res = await fetch(API_BASE + '/api/ps/chat/message', { + method: 'POST', + headers: authHeaders({ 'Content-Type': 'application/json' }), + body: JSON.stringify({ + dev_id: DEV_ID, + message: text, + history: conversationHistory.slice(-20) + }) + }); + + var data = await res.json(); + + if (data.reply) { + appendMessage('persona', data.reply); + conversationHistory.push({ role: 'assistant', content: data.reply }); + } + + if (data.build_ready) { + buildReady = true; + document.getElementById('buildBtn').style.display = 'inline-flex'; + } + } catch (_err) { + appendMessage('system', '消息发送失败,请稍后再试'); + } + + sendBtn.disabled = false; + input.focus(); +} + +/* ---- Key Handler ---- */ +function handleKeyDown(e) { + if (e.key === 'Enter' && !e.shiftKey) { + e.preventDefault(); + sendMessage(); + } +} + +/* ---- Render Message ---- */ +function appendMessage(role, content) { + var chatBody = document.getElementById('chatBody'); + var msgDiv = document.createElement('div'); + msgDiv.className = 'message message-' + role; + + var avatar = ''; + if (role === 'persona') avatar = '🧠'; + else if (role === 'user') avatar = '👤'; + else avatar = '⚙️'; + + msgDiv.innerHTML = avatar + '
' + escapeHtml(content) + '
'; + chatBody.appendChild(msgDiv); + chatBody.scrollTop = chatBody.scrollHeight; +} + +/* ---- Build Flow ---- */ +function handleBuild() { + document.getElementById('emailModal').style.display = 'flex'; + document.getElementById('emailInput').focus(); +} + +function closeEmailModal() { + document.getElementById('emailModal').style.display = 'none'; +} + +async function confirmBuild() { + var email = document.getElementById('emailInput').value.trim(); + if (!email) return; + + closeEmailModal(); + appendMessage('system', '🚀 开发任务已提交,完成后会发送到 ' + email); + + try { + await fetch(API_BASE + '/api/ps/build/start', { + method: 'POST', + headers: authHeaders({ 'Content-Type': 'application/json' }), + body: JSON.stringify({ + dev_id: DEV_ID, + email: email, + conversation: conversationHistory + }) + }); + } catch (_err) { + appendMessage('system', '任务提交失败,请稍后再试'); + } +} + +/* ---- Logout ---- */ +function handleLogout() { + sessionStorage.removeItem('dev_id'); + sessionStorage.removeItem('session_token'); + window.location.href = 'index.html'; +} + +/* ---- Helpers ---- */ +function authHeaders(extra) { + var headers = {}; + if (SESSION_TOKEN) { + headers['Authorization'] = 'Bearer ' + SESSION_TOKEN; + } + if (extra) { + Object.keys(extra).forEach(function (k) { headers[k] = extra[k]; }); + } + return headers; +} + +function escapeHtml(str) { + var div = document.createElement('div'); + div.appendChild(document.createTextNode(str)); + return div.innerHTML; +} + +function autoResizeTextarea(el) { + el.style.height = 'auto'; + el.style.height = Math.min(el.scrollHeight, 120) + 'px'; +} + +/* ---- Textarea auto-resize ---- */ +document.getElementById('msgInput').addEventListener('input', function () { + autoResizeTextarea(this); +}); diff --git a/docs/persona-studio/index.html b/docs/persona-studio/index.html new file mode 100644 index 00000000..89ef72c0 --- /dev/null +++ b/docs/persona-studio/index.html @@ -0,0 +1,141 @@ + + + + + + Persona Studio · 光湖人格体协助开发体验 + + + +
+
+

🌊 Persona Studio

+

光湖人格体协助开发体验

+
+ +
+

请输入你的开发编号

+

编号由管理员分配,格式:EXP-001

+ +
+ + +
+ +
+ +
+ + +

无需编号,直接与知秋对话

+ + +
+ + +
+ + + + diff --git a/docs/persona-studio/style.css b/docs/persona-studio/style.css new file mode 100644 index 00000000..274950d6 --- /dev/null +++ b/docs/persona-studio/style.css @@ -0,0 +1,491 @@ +/* ======================================== + Persona Studio · HoloLake Visual Style + ======================================== */ + +:root { + --primary: #0969da; + --primary-light: #ddf4ff; + --primary-dark: #0550ae; + --accent: #00d4aa; + --bg: #f6f8fa; + --bg-card: #ffffff; + --text: #1f2328; + --text-secondary: #656d76; + --border: #d0d7de; + --border-light: #e8ecf0; + --radius: 12px; + --shadow: 0 1px 3px rgba(0,0,0,0.08), 0 1px 2px rgba(0,0,0,0.06); + --shadow-lg: 0 4px 12px rgba(0,0,0,0.1); +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; + background: var(--bg); + color: var(--text); + line-height: 1.6; + min-height: 100vh; +} + +/* ---- Layout ---- */ +.container { + max-width: 900px; + margin: 0 auto; + min-height: 100vh; + display: flex; + flex-direction: column; +} + +/* ---- Guest Mode ---- */ +.guest-divider { + margin: 1.2rem 0; + text-align: center; + position: relative; +} + +.guest-divider::before, +.guest-divider::after { + content: ''; + position: absolute; + top: 50%; + width: 40%; + height: 1px; + background: var(--border); +} + +.guest-divider::before { left: 0; } +.guest-divider::after { right: 0; } + +.guest-divider span { + background: var(--bg-card); + padding: 0 0.8rem; + color: var(--text-secondary); + font-size: 0.9rem; +} + +.btn-guest { + width: 100%; + padding: 0.8rem; + font-size: 1.05rem; + background: linear-gradient(135deg, var(--accent), #0969da); + color: #fff; + border: none; + border-radius: 8px; + cursor: pointer; + transition: opacity 0.2s; + font-weight: 500; +} + +.btn-guest:hover { opacity: 0.9; } +.btn-guest:disabled { opacity: 0.6; cursor: not-allowed; } + +.guest-hint { + margin-top: 0.5rem; + font-size: 0.8rem; + color: var(--text-secondary); +} + +/* ---- Login Page ---- */ +.login-container { + justify-content: center; + align-items: center; + padding: 2rem; +} + +.logo-area { + text-align: center; + margin-bottom: 2rem; +} + +.logo-area h1 { + font-size: 2.4rem; + color: var(--primary); + margin-bottom: 0.5rem; +} + +.subtitle { + color: var(--text-secondary); + font-size: 1.1rem; +} + +.login-box { + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: var(--radius); + padding: 2.5rem; + width: 100%; + max-width: 420px; + box-shadow: var(--shadow-lg); + text-align: center; +} + +.login-box h2 { + font-size: 1.3rem; + margin-bottom: 0.5rem; +} + +.hint { + color: var(--text-secondary); + font-size: 0.9rem; + margin-bottom: 1.5rem; +} + +.login-box input[type="text"] { + width: 100%; + padding: 0.8rem 1rem; + font-size: 1.2rem; + text-align: center; + letter-spacing: 2px; + border: 2px solid var(--border); + border-radius: 8px; + outline: none; + transition: border-color 0.2s; + margin-bottom: 1rem; +} + +.login-box input[type="text"]:focus { + border-color: var(--primary); +} + +.login-box button[type="submit"] { + width: 100%; + padding: 0.8rem; + font-size: 1.1rem; + background: var(--primary); + color: #fff; + border: none; + border-radius: 8px; + cursor: pointer; + transition: background 0.2s; +} + +.login-box button[type="submit"]:hover { + background: var(--primary-dark); +} + +.login-box button[type="submit"]:disabled { + opacity: 0.6; + cursor: not-allowed; +} + +.error-msg { + margin-top: 1rem; + padding: 0.6rem 1rem; + background: #fef2f2; + color: #dc2626; + border-radius: 6px; + font-size: 0.9rem; +} + +.login-footer { + margin-top: 2rem; + color: var(--text-secondary); + font-size: 0.85rem; +} + +/* ---- Chat Page ---- */ +.chat-container { + padding: 0; +} + +.chat-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0.8rem 1.2rem; + background: var(--bg-card); + border-bottom: 1px solid var(--border); + position: sticky; + top: 0; + z-index: 10; +} + +.header-left { + display: flex; + align-items: center; + gap: 0.8rem; +} + +.persona-name { + font-size: 1.2rem; + font-weight: 600; +} + +.persona-role { + font-size: 0.85rem; + color: var(--text-secondary); +} + +.header-right { + display: flex; + align-items: center; + gap: 0.8rem; +} + +.dev-id-badge { + background: var(--primary-light); + color: var(--primary); + padding: 0.3rem 0.8rem; + border-radius: 20px; + font-size: 0.85rem; + font-weight: 500; +} + +/* ---- Chat Body ---- */ +.chat-body { + flex: 1; + overflow-y: auto; + padding: 1.2rem; + display: flex; + flex-direction: column; + gap: 1rem; +} + +.message { + display: flex; + gap: 0.8rem; + max-width: 85%; + animation: fadeIn 0.3s ease; +} + +.message-persona { + align-self: flex-start; +} + +.message-user { + align-self: flex-end; + flex-direction: row-reverse; +} + +.message-system { + align-self: center; + max-width: 90%; +} + +.avatar { + font-size: 1.5rem; + flex-shrink: 0; + width: 36px; + height: 36px; + display: flex; + align-items: center; + justify-content: center; +} + +.msg-content { + padding: 0.8rem 1rem; + border-radius: var(--radius); + line-height: 1.6; + white-space: pre-wrap; + word-break: break-word; +} + +.message-persona .msg-content { + background: var(--bg-card); + border: 1px solid var(--border-light); + box-shadow: var(--shadow); +} + +.message-user .msg-content { + background: var(--primary); + color: #fff; +} + +.message-system .msg-content { + background: var(--primary-light); + color: var(--primary-dark); + font-size: 0.9rem; + text-align: center; +} + +/* ---- Chat Input ---- */ +.chat-input-area { + padding: 0.8rem 1.2rem; + background: var(--bg-card); + border-top: 1px solid var(--border); +} + +.input-row { + display: flex; + gap: 0.6rem; + align-items: flex-end; +} + +.input-row textarea { + flex: 1; + padding: 0.7rem 1rem; + font-size: 1rem; + border: 2px solid var(--border); + border-radius: 8px; + resize: none; + outline: none; + font-family: inherit; + line-height: 1.5; + max-height: 120px; + transition: border-color 0.2s; +} + +.input-row textarea:focus { + border-color: var(--primary); +} + +.input-row button { + padding: 0.7rem 1.2rem; + background: var(--primary); + color: #fff; + border: none; + border-radius: 8px; + font-size: 1rem; + cursor: pointer; + white-space: nowrap; + transition: background 0.2s; +} + +.input-row button:hover { + background: var(--primary-dark); +} + +.input-row button:disabled { + opacity: 0.6; + cursor: not-allowed; +} + +.action-row { + margin-top: 0.6rem; + display: flex; + justify-content: flex-end; +} + +.btn-build { + padding: 0.6rem 1.5rem; + background: var(--accent); + color: #fff; + border: none; + border-radius: 8px; + font-size: 1rem; + font-weight: 600; + cursor: pointer; + display: inline-flex; + align-items: center; + gap: 0.4rem; + transition: opacity 0.2s; +} + +.btn-build:hover { + opacity: 0.9; +} + +/* ---- Buttons ---- */ +.btn-primary { + padding: 0.6rem 1.5rem; + background: var(--primary); + color: #fff; + border: none; + border-radius: 8px; + font-size: 1rem; + cursor: pointer; + transition: background 0.2s; +} + +.btn-primary:hover { + background: var(--primary-dark); +} + +.btn-secondary { + padding: 0.5rem 1rem; + background: transparent; + color: var(--text-secondary); + border: 1px solid var(--border); + border-radius: 8px; + font-size: 0.9rem; + cursor: pointer; + transition: background 0.2s; +} + +.btn-secondary:hover { + background: var(--bg); +} + +/* ---- Modal ---- */ +.modal { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.5); + display: flex; + justify-content: center; + align-items: center; + z-index: 100; +} + +.modal-content { + background: var(--bg-card); + border-radius: var(--radius); + padding: 2rem; + width: 90%; + max-width: 400px; + box-shadow: var(--shadow-lg); +} + +.modal-content h3 { + margin-bottom: 1rem; + font-size: 1.1rem; +} + +.modal-content input[type="email"] { + width: 100%; + padding: 0.7rem 1rem; + font-size: 1rem; + border: 2px solid var(--border); + border-radius: 8px; + outline: none; + margin-bottom: 1rem; + transition: border-color 0.2s; +} + +.modal-content input[type="email"]:focus { + border-color: var(--primary); +} + +.modal-actions { + display: flex; + gap: 0.8rem; + justify-content: flex-end; +} + +/* ---- Animation ---- */ +@keyframes fadeIn { + from { opacity: 0; transform: translateY(8px); } + to { opacity: 1; transform: translateY(0); } +} + +/* ---- Responsive ---- */ +@media (max-width: 600px) { + .logo-area h1 { + font-size: 1.8rem; + } + + .login-box { + padding: 1.5rem; + } + + .chat-header { + flex-wrap: wrap; + gap: 0.5rem; + } + + .persona-role { + display: none; + } + + .message { + max-width: 92%; + } +} diff --git a/persona-studio/README.md b/persona-studio/README.md index 92e93fd9..14c6a2ae 100644 --- a/persona-studio/README.md +++ b/persona-studio/README.md @@ -15,7 +15,7 @@ ## 👉 点击进入体验

- + Launch

diff --git a/persona-studio/frontend/chat.js b/persona-studio/frontend/chat.js index c108ecad..4fcf88ef 100644 --- a/persona-studio/frontend/chat.js +++ b/persona-studio/frontend/chat.js @@ -9,7 +9,7 @@ const API_BASE = (function () { if (location.hostname === 'localhost' || location.hostname === '127.0.0.1') { return 'http://localhost:3002'; } - return ''; + return 'https://guanghulab.com'; })(); /* ---- Init ---- */ diff --git a/persona-studio/frontend/index.html b/persona-studio/frontend/index.html index fe62ee64..89ef72c0 100644 --- a/persona-studio/frontend/index.html +++ b/persona-studio/frontend/index.html @@ -52,7 +52,7 @@ if (location.hostname === 'localhost' || location.hostname === '127.0.0.1') { return 'http://localhost:3002'; } - return ''; + return 'https://guanghulab.com'; } async function handleLogin(e) {