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 @@
## 👉 点击进入体验
-
+
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) {