]> acesimba.cloud Git - codebuddy-web.git/commitdiff
feat: 添加设计说明/帮助页(/help,可打印为 PDF),应用内「❓ 帮助」按钮入口
authorCodebuddy <codebuddy@localhost>
Mon, 17 Aug 2026 01:29:39 +0000 (09:29 +0800)
committerCodebuddy <codebuddy@localhost>
Mon, 17 Aug 2026 01:29:39 +0000 (09:29 +0800)
backend/app.py
frontend/help.html [new file with mode: 0644]
frontend/index.html

index 915d299f98c43ffec7dcd76850496166f007fd38..b9bb272ed4d1fe4b31654d1f38c11cfcee38b5f1 100644 (file)
@@ -453,6 +453,16 @@ async def index():
     return HTMLResponse(load_html(), headers={"Cache-Control": "no-store"})
 
 
+# 设计说明 / 帮助页(独立静态 HTML,可从应用内“❓ 帮助”打开,支持打印为 PDF)
+HELP_FILE = FRONTEND_DIR / "help.html"
+@app.get("/help")
+async def help_page():
+    if not HELP_FILE.exists():
+        return HTMLResponse("<h1>帮助文档缺失</h1>", status_code=404)
+    with open(HELP_FILE, "r", encoding="utf-8") as _f:
+        return HTMLResponse(_f.read(), headers={"Cache-Control": "no-store"})
+
+
 @app.post("/api/login")
 async def api_login(request: Request):
     body = await request.json()
diff --git a/frontend/help.html b/frontend/help.html
new file mode 100644 (file)
index 0000000..dc41b66
--- /dev/null
@@ -0,0 +1,171 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
+<title>Codebuddy Web Console · 设计说明</title>
+<style>
+  * { margin: 0; padding: 0; box-sizing: border-box; }
+  body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Microsoft YaHei", sans-serif;
+         color: #222; line-height: 1.7; background: #f5f6fa; padding: 32px 16px; }
+  .wrap { max-width: 920px; margin: 0 auto; background: #fff; border-radius: 14px; padding: 36px 40px; box-shadow: 0 4px 24px rgba(0,0,0,0.06); }
+  header { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; border-bottom: 2px solid #4ecca3; padding-bottom: 16px; margin-bottom: 8px; }
+  h1 { font-size: 24px; color: #1a1a2e; }
+  .sub { color: #888; font-size: 13px; margin-top: 4px; }
+  .btn-pdf { flex-shrink: 0; background: #4ecca3; color: #06281f; border: none; border-radius: 8px; padding: 8px 14px; cursor: pointer; font-size: 13px; font-weight: 600; }
+  .btn-pdf:hover { background: #6fd9b4; }
+  h2 { font-size: 19px; color: #1a1a2e; margin: 28px 0 10px; padding-left: 10px; border-left: 4px solid #4ecca3; }
+  h3 { font-size: 16px; color: #157a5e; margin: 18px 0 6px; }
+  p { margin: 6px 0; color: #333; }
+  ul, ol { margin: 6px 0 6px 22px; }
+  li { margin: 4px 0; }
+  code { background: #eef6f2; color: #157a5e; padding: 1px 6px; border-radius: 5px; font-size: 13px; font-family: "Cascadia Code", Menlo, Consolas, monospace; }
+  .tag { display: inline-block; background: #1a1a2e; color: #4ecca3; border-radius: 6px; padding: 2px 8px; font-size: 12px; margin: 2px 4px 2px 0; }
+  table { width: 100%; border-collapse: collapse; margin: 10px 0; font-size: 14px; }
+  th, td { text-align: left; padding: 8px 10px; border-bottom: 1px solid #e3e6ee; vertical-align: top; }
+  th { background: #f0f3f8; color: #1a1a2e; }
+  .note { background: #fff8e6; border: 1px solid #ffe08a; border-radius: 8px; padding: 10px 14px; margin: 10px 0; font-size: 13px; color: #6b5a1f; }
+  .page { background: #f0f3ff; border: 1px solid #c9d4ff; border-radius: 8px; padding: 12px 16px; margin: 10px 0; }
+  footer { margin-top: 32px; padding-top: 14px; border-top: 1px solid #eee; color: #aaa; font-size: 12px; text-align: center; }
+  a { color: #157a5e; }
+  @media print {
+    body { background: #fff; padding: 0; }
+    .wrap { box-shadow: none; max-width: 100%; padding: 0 8px; }
+    .btn-pdf { display: none; }
+    h2 { page-break-after: avoid; }
+    .page, .note { break-inside: avoid; }
+  }
+  @page { margin: 16mm; }
+</style>
+</head>
+<body>
+<div class="wrap">
+  <header>
+    <div>
+      <h1>Codebuddy Web Console · 设计说明</h1>
+      <div class="sub">通过浏览器远程使用 Codebuddy CLI 的 Web 控制台 · 多会话 / 全局技能 / 文件上传 / 移动端适配</div>
+    </div>
+    <button class="btn-pdf" onclick="window.print()">⬇ 下载 PDF</button>
+  </header>
+
+  <h2>一、整体架构</h2>
+  <ul>
+    <li><b>后端</b>:FastAPI + WebSocket PTY。每个“任务”对应一个独立运行的 <code>codebuddy</code> CLI 进程。</li>
+    <li><b>前端</b>:单文件原生 HTML(无前端框架)。通过 URL 参数区分页面:<code>/</code> 为任务列表页,<code>/?task=&lt;任务ID&gt;</code> 为对应任务的终端页。</li>
+    <li><b>技能</b>:存储于全局目录 <code>~/.codebuddy/skills</code>。上传后对所有会话可见;运行中的会话可“热加载”即时生效,否则下次打开会话时由 codebuddy 自动发现。</li>
+    <li><b>上传文件</b>:统一存于服务端的 <code>data/pastes/</code> 目录,并可在“已上传文件”面板中集中管理。</li>
+  </ul>
+
+  <h2>二、页面与功能</h2>
+
+  <div class="page">
+    <h3>1. 登录页</h3>
+    <ul>
+      <li>输入访问密码进入控制台(密码保存在浏览器 <code>localStorage</code>)。</li>
+    </ul>
+  </div>
+
+  <div class="page">
+    <h3>2. 任务列表页(首页)</h3>
+    <p>默认展示“启用中”的任务,可勾选“显示全部任务”查看包括已暂停的全部任务。</p>
+    <h3>左侧 · 技能侧边栏(🧩 技能 全局)</h3>
+    <ul>
+      <li><b>上传</b>:选择 skill 的 zip(须以单个 skill 目录为顶层,内含 <code>SKILL.md</code>),上传后对所有会话全局可见。</li>
+      <li><b>技能列表卡片</b>:每张卡片提供 <span class="tag">更新</span><span class="tag">编辑</span><span class="tag">加载</span><span class="tag">删除</span>。
+        <ul>
+          <li><b>更新</b>:用新 zip 覆盖同名 skill(按 zip 内声明名匹配,避免产生重复目录)。</li>
+          <li><b>编辑</b>:直接修改 <code>SKILL.md</code> 内容。</li>
+          <li><b>加载</b>:选择“运行中的会话”注入热加载通知(可多选,或一键“全部运行中的会话”);若无运行会话则技能已全局就位,下次打开自动发现。</li>
+          <li><b>删除</b>:移除该全局 skill。</li>
+        </ul>
+      </li>
+      <li><b>📂 已上传文件</b>:打开“已上传文件”管理弹窗(详见第 4 节)。</li>
+    </ul>
+    <h3>主区 · 任务卡片</h3>
+    <ul>
+      <li>展示:任务名、工作目录、状态、最近使用时间。</li>
+      <li>状态指示:<span class="tag">● 前台已登录</span><span class="tag">⚙ 后台运行中</span><span class="tag">⏸ 后台等待中</span><span class="tag">⏳ 后台任务待确认</span><span class="tag">⏸ 已暂停</span><span class="tag">○ 空闲</span>。</li>
+      <li>操作:打开终端、重启会话、暂停/恢复、删除(可同时删除历史会话记录与工作目录)。</li>
+    </ul>
+    <p class="note">列表页每 5 秒自动刷新一次,实时反映各会话状态。</p>
+  </div>
+
+  <div class="page">
+    <h3>3. 终端页(<code>/?task=&lt;ID&gt;</code>)</h3>
+    <h3>顶部栏</h3>
+    <ul>
+      <li>连接状态指示灯 + 文本、任务名、工作目录。</li>
+      <li>模型切换下拉(切换后重启会话以应用)。</li>
+      <li>按钮:<span class="tag">↻ 重启会话</span><span class="tag">≡ 列表</span><span class="tag">📋 粘贴</span><span class="tag">🧩 技能</span><span class="tag">❓ 帮助</span><span class="tag">✕ 关闭</span>。</li>
+    </ul>
+    <h3>终端输出区(xterm)</h3>
+    <ul>
+      <li>实时显示 CLI 输出;新输出自动滚动贴底。</li>
+      <li>手动上滑查看历史时,右下角出现 <span class="tag">↓ 回到底部</span> 按钮,点击即回到最新。</li>
+    </ul>
+    <h3>粘贴框(📋)</h3>
+    <ul>
+      <li>文本直接输入;<code>Ctrl+Enter</code> 发送到终端输入行(不自动提交,需自行回车)。</li>
+      <li><b>📎 附件</b>:支持上传 <b>图片 / 视频 / zip / 任意格式</b> 文件,单文件上限 <b>5MB</b>。</li>
+      <li>待发送文件以 chip 展示(图标区分 🖼 图片 / 🎬 视频 / 📦 压缩包 / 📄 其他)。</li>
+      <li>发送规则:图片包装为 <code>&lt;image_local_path&gt;路径&lt;/image_local_path&gt;</code>;其它文件发送其本地路径文本,供命令行引用。</li>
+      <li>粘贴框内“已上传文件”区:列出本次/历史上传文件,可单独删除。</li>
+    </ul>
+    <h3>技能弹窗(🧩,终端页内)</h3>
+    <ul>
+      <li>功能与列表页左侧技能侧边栏一致(上传/更新/编辑/加载/删除)。</li>
+    </ul>
+  </div>
+
+  <div class="page">
+    <h3>4. 已上传文件弹窗</h3>
+    <p>从列表页「📂 已上传文件」按钮打开,以表格管理所有上传文件:</p>
+    <table>
+      <thead><tr><th>列</th><th>说明</th></tr></thead>
+      <tbody>
+        <tr><td>选择框</td><td>每行可勾选;表头“全选”一键勾选全部。</td></tr>
+        <tr><td>文件名</td><td>服务端存储的文件名。</td></tr>
+        <tr><td>上传时间</td><td>文件写入时间(本地时间)。</td></tr>
+        <tr><td>所属会话任务</td><td>上传时所在的终端会话名;历史文件(升级前上传)显示 <code>—</code>。</td></tr>
+        <tr><td>文件类型</td><td>按扩展名/格式显示,如 <code>.png</code> / <code>.zip</code> / <code>.mp4</code>。</td></tr>
+        <tr><td>操作</td><td>单条“删除”。</td></tr>
+      </tbody>
+    </table>
+    <ul>
+      <li><b>批量删除</b>:勾选多个后点“删除所选”(带二次确认)。</li>
+      <li>删除同时从服务端磁盘移除文件,并清理其会话归属索引。</li>
+    </ul>
+  </div>
+
+  <h2>三、移动端(iPad / 手机)适配</h2>
+  <ul>
+    <li><b>顶栏固定</b>:顶部菜单栏锁定在视口顶部,不随页面滚动;整页只有终端区内部滚动。</li>
+    <li><b>键盘适配</b>:软键盘弹起时,终端区自动缩小到键盘上方,输入内容始终可见。</li>
+    <li><b>自动滚动</b>:CLI 新输出自动贴底,无需手动下拉。</li>
+    <li><b>标签页标题</b>:浏览器标签页显示为 <code>会话名 - CLI</code>(如 <code>Words - CLI</code>),便于多标签区分。</li>
+    <li><b>安全区域</b>:适配刘海与底部指示条(<code>env(safe-area-inset)</code>)。</li>
+  </ul>
+
+  <h2>四、快捷操作</h2>
+  <ul>
+    <li><code>Ctrl+Enter</code>:在粘贴框发送内容。</li>
+    <li><code>Esc</code>:关闭弹窗(粘贴框 / 技能框 / 已上传文件框)。</li>
+    <li>多会话选择 + “全部运行中的会话”:一键把 skill 热加载到多个会话。</li>
+  </ul>
+
+  <h2>五、常见问题</h2>
+  <div class="note">
+    <b>Q:上传视频/zip 提示不支持或过大?</b><br>
+    服务端已内置“任意格式 + 5MB”支持;若仍报错,多为服务端尚未重启生效,重启 <code>codebuddy-web.service</code> 即可。
+  </div>
+  <div class="note">
+    <b>Q:已上传文件的“所属会话任务”是空/—?</b><br>
+    仅“升级后、从终端页新上传”的文件会记录所属会话;升级前上传的历史文件因当时未记录归属,故显示 <code>—</code>,无法反查。
+  </div>
+
+  <footer>
+    Codebuddy Web Console · 设计说明(随仓库 <code>frontend/help.html</code> 提供) · 在应用内点「❓ 帮助」可随时打开
+  </footer>
+</div>
+</body>
+</html>
index 069c0e4353d93cd1bab99d034e4a2436c68973a6..ab739c6aec91647944e5be3d84f26191e40406f6 100644 (file)
@@ -236,6 +236,7 @@ body { position: fixed; top: 0; left: 0; right: 0; bottom: 0; width: 100%; heigh
     <h2>任务清单 <small id="picker-subtitle"></small></h2>
     <div style="display:flex; gap:16px; align-items:center;">
       <label class="picker-toggle"><input type="checkbox" id="show-all-tasks"> 显示全部任务</label>
+      <button class="action-btn" id="btn-help-picker" title="设计说明 / 帮助" onclick="window.open('/help','_blank')">❓ 帮助</button>
       <button class="action-btn" id="btn-logout-picker">退出登录</button>
     </div>
   </div>
@@ -308,6 +309,7 @@ body { position: fixed; top: 0; left: 0; right: 0; bottom: 0; width: 100%; heigh
       <button class="action-btn" id="btn-list" title="打开任务列表">≡ 列表</button>
       <button class="action-btn" id="btn-paste" title="粘贴文字或图片">📋 粘贴</button>
       <button class="action-btn" id="btn-skills" title="管理自定义 skill">🧩 技能</button>
+      <button class="action-btn" id="btn-help" title="设计说明 / 帮助" onclick="window.open('/help','_blank')">❓ 帮助</button>
       <button class="action-btn" id="btn-close" title="关闭窗口">✕ 关闭</button>
     </div>
   </div>