feihong-code 7.0.0 → 7.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/.github/workflows/ci.yml +180 -140
  2. package/.github/workflows/release.yml +200 -0
  3. package/CHANGELOG.md +94 -65
  4. package/README.md +609 -586
  5. package/dist/agent/browser-agent.js +354 -0
  6. package/dist/agent/browser-agent.js.map +1 -0
  7. package/dist/agent/change-manager.js +433 -0
  8. package/dist/agent/change-manager.js.map +1 -0
  9. package/dist/agent/code-rag.js +293 -0
  10. package/dist/agent/code-rag.js.map +1 -0
  11. package/dist/agent/code-writer.js +13 -1
  12. package/dist/agent/code-writer.js.map +1 -1
  13. package/dist/agent/completion-engine.js +553 -0
  14. package/dist/agent/completion-engine.js.map +1 -0
  15. package/dist/agent/completion-postprocess.js +109 -0
  16. package/dist/agent/completion-postprocess.js.map +1 -0
  17. package/dist/agent/context-budget.js +121 -0
  18. package/dist/agent/context-budget.js.map +1 -0
  19. package/dist/agent/context-compactor.js +235 -10
  20. package/dist/agent/context-compactor.js.map +1 -1
  21. package/dist/agent/custom-agent.js +368 -0
  22. package/dist/agent/custom-agent.js.map +1 -0
  23. package/dist/agent/design-to-code.js +218 -0
  24. package/dist/agent/design-to-code.js.map +1 -0
  25. package/dist/agent/event-driven-agent.js +359 -0
  26. package/dist/agent/event-driven-agent.js.map +1 -0
  27. package/dist/agent/git-integration.js +324 -0
  28. package/dist/agent/git-integration.js.map +1 -0
  29. package/dist/agent/layered-memory.js +329 -0
  30. package/dist/agent/layered-memory.js.map +1 -0
  31. package/dist/agent/lint.js +121 -0
  32. package/dist/agent/lint.js.map +1 -0
  33. package/dist/agent/multi-agent.js +359 -0
  34. package/dist/agent/multi-agent.js.map +1 -0
  35. package/dist/agent/orchestrator.js +136 -25
  36. package/dist/agent/orchestrator.js.map +1 -1
  37. package/dist/agent/prompts.js +54 -54
  38. package/dist/agent/quality-gate.js +139 -0
  39. package/dist/agent/quality-gate.js.map +1 -1
  40. package/dist/agent/self-correction.js +274 -0
  41. package/dist/agent/self-correction.js.map +1 -0
  42. package/dist/agent/self-heal.js +47 -17
  43. package/dist/agent/self-heal.js.map +1 -1
  44. package/dist/agent/solo-agent.js +321 -0
  45. package/dist/agent/solo-agent.js.map +1 -0
  46. package/dist/agent/symbol-index.js +258 -28
  47. package/dist/agent/symbol-index.js.map +1 -1
  48. package/dist/agent/team-collaboration.js +252 -0
  49. package/dist/agent/team-collaboration.js.map +1 -0
  50. package/dist/agent/type-checker.js +229 -0
  51. package/dist/agent/type-checker.js.map +1 -0
  52. package/dist/cli/commands.js +9 -0
  53. package/dist/cli/commands.js.map +1 -1
  54. package/dist/cli/index.js +9 -0
  55. package/dist/cli/index.js.map +1 -1
  56. package/dist/cli/multi-pane-tui.js +217 -0
  57. package/dist/cli/multi-pane-tui.js.map +1 -0
  58. package/dist/cli/run.js +130 -40
  59. package/dist/cli/run.js.map +1 -1
  60. package/dist/cli/tui-run.js +79 -0
  61. package/dist/cli/tui-run.js.map +1 -0
  62. package/dist/cli/tui.js.map +1 -1
  63. package/dist/cli/version.js +1 -1
  64. package/dist/integrations/collaboration.js +219 -0
  65. package/dist/integrations/collaboration.js.map +1 -0
  66. package/dist/integrations/figma.js +307 -0
  67. package/dist/integrations/figma.js.map +1 -0
  68. package/dist/integrations/sso.js +327 -0
  69. package/dist/integrations/sso.js.map +1 -0
  70. package/dist/knowledge/library.js +301 -0
  71. package/dist/knowledge/library.js.map +1 -0
  72. package/dist/lsp/lsp-client.js +183 -0
  73. package/dist/lsp/lsp-client.js.map +1 -0
  74. package/dist/lsp/lsp-service.js +159 -0
  75. package/dist/lsp/lsp-service.js.map +1 -0
  76. package/dist/plugins/manager.js +380 -0
  77. package/dist/plugins/manager.js.map +1 -0
  78. package/dist/runtime/event-log.js.map +1 -1
  79. package/dist/shared/i18n.js +108 -100
  80. package/dist/shared/i18n.js.map +1 -1
  81. package/dist/tools/browser/browser.tool.js +217 -0
  82. package/dist/tools/browser/browser.tool.js.map +1 -0
  83. package/dist/tools/generator/code-generator.js +40 -40
  84. package/dist/tools/generator/test-generator.js +9 -9
  85. package/dist/tools/index.js +2 -0
  86. package/dist/tools/index.js.map +1 -1
  87. package/dist/tools/shell/exec.js +73 -11
  88. package/dist/tools/shell/exec.js.map +1 -1
  89. package/dist/tools/shell/run-shell.tool.js +8 -2
  90. package/dist/tools/shell/run-shell.tool.js.map +1 -1
  91. package/dist/training/completion-evaluator.js +213 -0
  92. package/dist/training/completion-evaluator.js.map +1 -0
  93. package/dist/training/fim-data.js +248 -0
  94. package/dist/training/fim-data.js.map +1 -0
  95. package/dist/voice/voice-programming.js +223 -0
  96. package/dist/voice/voice-programming.js.map +1 -0
  97. package/dist/web/extra-apis.js +440 -0
  98. package/dist/web/extra-apis.js.map +1 -0
  99. package/dist/web/public/css/style.css +1729 -1671
  100. package/dist/web/public/index.html +1242 -990
  101. package/dist/web/public/js/api.js +555 -382
  102. package/dist/web/public/js/app.js +2210 -2210
  103. package/dist/web/public/js/mock-api.js +234 -0
  104. package/dist/web/public/js/monaco-editor.js +363 -0
  105. package/dist/web/public/js/ui.js +2251 -1059
  106. package/dist/web/public/js/utils.js +214 -214
  107. package/dist/web/public/manifest.json +59 -0
  108. package/dist/web/public/service-worker.js +173 -0
  109. package/dist/web/server.js +1116 -45
  110. package/dist/web/server.js.map +1 -1
  111. package/dist/web/task-queue.js +22 -2
  112. package/dist/web/task-queue.js.map +1 -1
  113. package/docs/BENCHMARK_REPORT_en.md +386 -329
  114. package/docs/BENCHMARK_REPORT_zh.md +386 -329
  115. package/docs/DPA.md +63 -0
  116. package/docs/DPA/346/225/260/346/215/256/345/244/204/347/220/206/345/215/217/350/256/256/346/250/241/346/235/277_v1.0.md +67 -0
  117. package/docs/SECURITY_WHITEPAPER.md +74 -0
  118. package/docs/SWE_BENCH_REPORT.md +55 -0
  119. package/docs/TECHNICAL_SPEC_en.md +292 -292
  120. package/docs/TECHNICAL_SPEC_zh.md +292 -292
  121. package/docs/UPDATE_NOTES_en.md +159 -159
  122. package/docs/UPDATE_NOTES_zh.md +159 -159
  123. package/docs/UPGRADE_7.2.0.md +309 -0
  124. package/docs/UPGRADE_GUIDE_7_5.md +86 -0
  125. package/docs/geo-feihong-code.html +391 -0
  126. package/docs//345/205/250/351/235/242/345/244/215/347/233/230_50/350/275/256/346/267/261/345/272/246/345/256/241/350/256/241_v7.2.0.md +208 -0
  127. package/docs//345/205/250/351/235/242/345/244/215/347/233/230_6/351/241/271/351/207/215/347/202/271/346/240/270/346/237/245_v7.2.0.md +152 -0
  128. package/docs//345/205/250/351/235/242/345/244/215/347/233/230_/350/277/220/350/241/214/346/227/266/345/256/236/346/265/213/347/211/210_v7.2.0.md +271 -0
  129. package/docs//345/220/210/350/247/204/350/256/244/350/257/201/345/207/206/345/244/207/346/270/205/345/215/225_v7.2.0.md +59 -0
  130. package/docs//345/256/211/345/205/250/347/231/275/347/232/256/344/271/246_v7.2.0.md +82 -0
  131. package/electron/main.js +404 -404
  132. package/package.json +175 -167
  133. package/templates/skills/api-design/SKILL.md +27 -0
  134. package/templates/skills/code-review/SKILL.md +35 -0
  135. package/templates/skills/dependency-upgrade/SKILL.md +29 -0
  136. package/templates/skills/doc-gen/SKILL.md +29 -0
  137. package/templates/skills/git-flow/SKILL.md +26 -0
  138. package/templates/skills/onboarding/SKILL.md +27 -0
  139. package/templates/skills/performance/SKILL.md +29 -0
  140. package/templates/skills/refactor/SKILL.md +28 -0
  141. package/templates/skills/security-audit/SKILL.md +28 -0
  142. package/templates/skills/test-gen/SKILL.md +30 -0
  143. package/tool-schema.json +197 -197
  144. package/dist/hello.js +0 -14
  145. package/dist/hello.js.map +0 -1
  146. package/dist/self-evolve/hook.ts +0 -80
  147. package/dist/self-evolve/manager.d.ts +0 -8
  148. package/dist/web/web-config.js +0 -143
  149. package/dist/web/web-config.js.map +0 -1
@@ -1,990 +1,1242 @@
1
- <!DOCTYPE html>
2
- <html lang="zh">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title data-i18n="app.title_login">飞虹 Code 控制台 / fhcode Console</title>
7
- <link rel="stylesheet" href="css/style.css">
8
- </head>
9
- <body>
10
- <div id="loginOverlay">
11
- <div class="login-card">
12
- <h2 data-i18n="app.title_login">飞虹 Code 控制台</h2>
13
- <p data-i18n="app.login_hint">请输入手机号码直接登录</p>
14
- <label for="loginPhone" data-i18n="login.phone_label">手机号码</label>
15
- <input type="text" id="loginPhone" autocomplete="off" placeholder="如 13800138000" />
16
- <button id="loginBtn" data-i18n="login.btn_login">手机号登录</button>
17
- <div class="login-status" id="loginStatus"></div>
18
- </div>
19
- </div>
20
-
21
- <div class="app-layout" id="appLayout">
22
- <!-- 顶部导航栏 -->
23
- <header class="topbar">
24
- <div class="topbar-brand">
25
- <div class="logo">🦞</div>
26
- <span data-i18n="app.brand">飞虹 Code</span>
27
- </div>
28
- <nav class="topbar-nav">
29
- <div class="topbar-nav-item active" data-nav="chat" data-i18n="nav.chat">💬 对话</div>
30
- <div class="topbar-nav-item" data-nav="automations" data-i18n="nav.automations">⚡ 自动化</div>
31
- <div class="topbar-nav-item" data-nav="templates" data-i18n="nav.templates">📚 模板库</div>
32
- <div class="topbar-nav-item" data-nav="market" data-i18n="nav.market">🧩 插件</div>
33
- <div class="topbar-nav-item" data-nav="office" data-i18n="nav.office">📎 办公</div>
34
- <div class="topbar-nav-item" data-nav="memory" data-i18n="nav.memory">🧠 记忆</div>
35
- <div class="topbar-nav-item" data-nav="release" data-i18n="nav.release">🚀 发布</div>
36
- </nav>
37
- <div class="topbar-spacer"></div>
38
- <div class="lang-switcher">
39
- <button class="lang-btn active" data-lang="zh">中文</button>
40
- <button class="lang-btn" data-lang="en">EN</button>
41
- </div>
42
- <div class="topbar-user" id="topbarUser">
43
- <div class="topbar-avatar">🦐</div>
44
- <span class="topbar-phone" id="topbarPhone">未登录</span>
45
- </div>
46
- </header>
47
-
48
- <!-- 主体区 -->
49
- <div class="main-area">
50
- <!-- 左侧图标导航 -->
51
- <aside class="sidebar">
52
- <!-- 导航菜单 -->
53
- <div class="sidebar-section">
54
- <div class="sidebar-section-title" data-i18n="sidebar.nav">导航</div>
55
- <div class="sidebar-icon active" data-nav="chat" title="对话任务" data-i18n="sidebar.chat">
56
- <span class="icon">💬</span>
57
- <span class="label" data-i18n="sidebar.chat">对话任务</span>
58
- </div>
59
- <div class="sidebar-icon" data-nav="automations" title="自动化" data-i18n="sidebar.automations">
60
- <span class="icon">⚡</span>
61
- <span class="label" data-i18n="sidebar.automations">自动化</span>
62
- </div>
63
- <div class="sidebar-icon" data-nav="templates" title="模板库" data-i18n="sidebar.templates">
64
- <span class="icon">📚</span>
65
- <span class="label" data-i18n="sidebar.templates">模板库</span>
66
- </div>
67
- <div class="sidebar-icon" data-nav="market" title="插件市场" data-i18n="sidebar.market">
68
- <span class="icon">🧩</span>
69
- <span class="label" data-i18n="sidebar.market">插件市场</span>
70
- </div>
71
- <div class="sidebar-icon" data-nav="office" title="办公助理" data-i18n="sidebar.office">
72
- <span class="icon">📎</span>
73
- <span class="label" data-i18n="sidebar.office">办公助理</span>
74
- </div>
75
- <div class="sidebar-icon" data-nav="nodes" title="节点管理" data-i18n="sidebar.nodes">
76
- <span class="icon">🔗</span>
77
- <span class="label" data-i18n="sidebar.nodes">节点管理</span>
78
- </div>
79
- <div class="sidebar-icon" data-nav="memory" title="记忆系统" data-i18n="sidebar.memory">
80
- <span class="icon">🧠</span>
81
- <span class="label" data-i18n="sidebar.memory">记忆系统</span>
82
- </div>
83
- <div class="sidebar-icon" data-nav="release" title="产品发布" data-i18n="sidebar.release">
84
- <span class="icon">🚀</span>
85
- <span class="label" data-i18n="sidebar.release">产品发布</span>
86
- </div>
87
- </div>
88
-
89
- <!-- 任务列表 -->
90
- <div class="sidebar-section" id="taskListSection" style="display:none;">
91
- <div class="sidebar-section-title" style="display:flex;align-items:center;justify-content:space-between;">
92
- <span data-i18n="sidebar.task_list">任务列表 <span class="badge" id="taskCountBadge" style="margin-left:4px;">0</span></span>
93
- <button class="new-task-btn" id="newTaskBtn" title="新建对话任务" data-i18n="sidebar.chat">+ 新建任务</button>
94
- </div>
95
- <div id="taskListContainer" style="max-height:300px;overflow-y:auto;">
96
- <div class="empty" style="font-size:11px;padding:8px;" data-i18n="empty.no_tasks">暂无任务</div>
97
- </div>
98
- </div>
99
-
100
- <div class="sidebar-spacer"></div>
101
-
102
- <!-- 用户和设置 -->
103
- <div class="sidebar-section">
104
- <div class="sidebar-icon" id="sidebarUser" title="用户菜单" data-i18n="sidebar.user">
105
- <span class="icon">👤</span>
106
- <span class="label" data-i18n="sidebar.user">用户</span>
107
- </div>
108
- <div class="sidebar-icon" id="sidebarSettings" title="设置" data-i18n="sidebar.settings">
109
- <span class="icon">⚙️</span>
110
- <span class="label" data-i18n="sidebar.settings">设置</span>
111
- </div>
112
- </div>
113
- </aside>
114
-
115
- <!-- 中间内容区 -->
116
- <main class="chat-area" id="chatArea">
117
- <!-- 任务上下文头部 -->
118
- <div class="task-context-header" id="taskContextHeader">
119
- <div class="tch-left">
120
- <div class="tch-title" id="tchTitle" data-i18n="task.not_selected">未选择任务</div>
121
- <div class="tch-sub" id="tchSub" data-i18n="sidebar.task_list">从左侧任务列表选择,或在下方输入指令发起新任务</div>
122
- </div>
123
- <div class="tch-right">
124
- <button class="ghost-btn" id="tchNewTask" title="新建对话任务" data-i18n="sidebar.chat">+ 新建任务</button>
125
- <span class="badge" id="tchStatus">—</span>
126
- <span class="tch-time" id="tchTime"></span>
127
- <button class="ghost-btn" id="tchStop" title="停止当前任务" style="display:none;">⏹ 停止</button>
128
- <button class="ghost-btn" id="tchRefresh" title="刷新当前任务" data-i18n="task.refresh">⟳</button>
129
- </div>
130
- </div>
131
-
132
- <!-- 对话视图 -->
133
- <div class="conv view active" data-view="chat">
134
- <div class="messages" id="messages">
135
- <div class="msg sys" data-i18n="btn.new_task">点击「+ 新建任务」开启一个新任务,或直接在下方向当前任务发送消息——所有对话都会归属同一个任务运行。</div>
136
- </div>
137
-
138
- <div class="input-area">
139
- <div class="input-bar">
140
- <div class="staged-area" id="stagedArea"></div>
141
- <textarea id="goalInput" placeholder="输入指令,消息将归属当前任务持续对话;点上方「+ 新建任务」可开启新任务(创建 → 推理 → 工具验证 → 闭环全程追踪)" data-i18n="btn.new_task"></textarea>
142
- <div class="input-toolbar">
143
- <div class="dropdown" id="convMenuWrap">
144
- <span class="pill" id="convMenuBtn" title="更多操作" data-i18n="chat.menu">+ 菜单</span>
145
- <div class="dropdown-menu" id="convMenu">
146
- <div class="dropdown-item" data-action="screenshot" data-i18n="chat.screenshot">📷 截图</div>
147
- <div class="dropdown-item" data-action="upload-file" data-i18n="chat.upload_file">📄 上传文件</div>
148
- <div class="dropdown-item" data-action="upload-image" data-i18n="chat.upload_image">🖼 上传图片</div>
149
- <div class="dropdown-item" data-action="direct-mode" data-i18n="chat.direct_mode">🖥 电脑操作</div>
150
- <div class="dropdown-item" data-action="voice" data-i18n="chat.voice">🎤 语音输入</div>
151
- <div class="dropdown-divider"></div>
152
- <div class="dropdown-item" data-action="agent-type" data-i18n="chat.agent_type">🤖 选择智能体类型</div>
153
- </div>
154
- </div>
155
- <button class="pill" id="screenshotBtn" title="截图(框选屏幕区域发给 AI)" data-i18n="chat.screenshot">📷 截图</button>
156
- <button class="pill" id="voiceBtn" title="语音输入(点击开始/停止)" data-i18n="chat.voice">🎤 语音</button>
157
- <span class="pill" id="skillPill" title="当前智能体" data-i18n="chat.agent_default">🤖 通用助手</span>
158
- <span class="pill" id="directModePill" style="display:none;" title="电脑操作模式已开启" data-i18n="chat.direct_mode">🖥 电脑操作</span>
159
- <span id="voiceBadge" class="voice-badge" style="display:none;" data-i18n="chat.listening">● 正在听…</span>
160
- <span class="spacer"></span>
161
- <button id="sendBtn" data-i18n="chat.send">▶ 发送</button>
162
- </div>
163
- </div>
164
- <div class="workspace-bar">
165
- <button class="wb-select" id="workspacePickBtn" title="选择工作区文件夹" data-i18n="modal.new_task_workspace">
166
- <span class="wb-icon">📂</span>
167
- <span class="wb-label" id="workspaceCwdBottom" data-i18n="common.loading">加载中…</span>
168
- <span class="wb-arrow">▾</span>
169
- </button>
170
- <div class="wb-perm" id="workspacePermBadge" title="点击配置权限">
171
- <span>🛡️</span>
172
- <span id="workspacePermLabel" data-i18n="perm.default">默认权限</span>
173
- </div>
174
- </div>
175
- <div class="call-bar">
176
- <span class="call-hint" data-i18n="call.hint">通话</span>
177
- <button id="voiceCallBtn" class="call-btn" data-i18n="call.voice">📞 语音</button>
178
- <button id="videoCallBtn" class="call-btn" data-i18n="call.video">🎥 视频</button>
179
- <button id="hangupCallBtn" class="call-btn hangup" style="display:none;" data-i18n="call.hangup">⛔ 挂断</button>
180
- <span id="callStatus" class="call-status"></span>
181
- </div>
182
- </div>
183
- </div>
184
-
185
- <!-- 自动化页面 -->
186
- <div class="page-view" data-view="automations">
187
- <div class="page-head">
188
- <div data-i18n="nav.automations"><h2>⚡ 自动化</h2><div class="sub">把常用目标存成指令,一键发起任务</div></div>
189
- <button id="newAutoBtn" data-i18n="btn.new_automation">+ 新建指令</button>
190
- </div>
191
- <div class="section-title">常用快捷指令</div>
192
- <div class="grid" id="builtinAutoGrid"></div>
193
- <div class="section-title" style="margin-top:20px;">我的指令</div>
194
- <div class="grid" id="autoGrid" data-i18n="empty.no_automations"><div class="empty">还没有自定义指令,点击上方「新建指令」或从常用指令保存</div></div>
195
- </div>
196
-
197
- <!-- 模板库页面 -->
198
- <div class="page-view" data-view="templates">
199
- <div class="page-head">
200
- <div data-i18n="nav.templates"><h2>📚 模板库</h2><div class="sub">点击模板即可填充到输入框</div></div>
201
- <button id="newTplBtn" data-i18n="btn.save_template">+ 保存当前为模板</button>
202
- </div>
203
- <div class="section-title" data-i18n="tpl.builtin">内置模板</div>
204
- <div class="grid" id="builtinGrid"></div>
205
- <div class="section-title" style="margin-top:20px;" id="nodeTplTitle" data-i18n="tpl.node">来自节点</div>
206
- <div class="grid" id="nodeTplGrid"><div class="empty">暂无节点模板,去「节点管理」添加节点</div></div>
207
- <div class="section-title" style="margin-top:20px;" id="customTplTitle" data-i18n="tpl.custom">自定义来源</div>
208
- <div class="grid" id="customTplGrid"><div class="empty">暂无自定义来源模板</div></div>
209
- <div class="section-title" style="margin-top:20px;" data-i18n="tpl.my">我的模板</div>
210
- <div class="grid" id="userTplGrid" data-i18n="empty.no_templates"><div class="empty">暂无自定义模板</div></div>
211
- </div>
212
-
213
- <!-- 插件市场页面 -->
214
- <div class="page-view" data-view="market">
215
- <div class="page-head">
216
- <div data-i18n="nav.market"><h2>🧩 插件市场</h2><div class="sub">聚合 ClawHub 与 Agent-Foundry 技能生态</div></div>
217
- <div class="row" style="flex:0 0 auto; gap:8px;">
218
- <input type="text" id="marketSearch" placeholder="搜索…" style="margin:0;width:160px;" data-i18n="market.search_placeholder" />
219
- <select id="marketSource" style="margin:0;width:130px;">
220
- <option value="all" data-i18n="market.source_all">全部来源</option>
221
- <option value="clawhub">ClawHub</option>
222
- <option value="agent-foundry">Agent-Foundry</option>
223
- <option value="node">节点</option>
224
- <option value="custom">自定义来源</option>
225
- </select>
226
- <button id="marketRefresh" data-i18n="btn.refresh">刷新</button>
227
- </div>
228
- </div>
229
- <div class="grid" id="marketGrid" data-i18n="common.loading"><div class="empty">加载中…</div></div>
230
- <div class="section-title" style="margin-top:20px;" data-i18n="market.installed">已安装</div>
231
- <div class="grid" id="installedGrid" data-i18n="market.installed"><div class="empty">暂无已安装技能</div></div>
232
- </div>
233
-
234
- <!-- 办公助理页面 -->
235
- <div class="page-view" data-view="office">
236
- <div class="page-head">
237
- <div data-i18n="nav.office"><h2>📎 办公助理</h2><div class="sub">文档处理快捷入口,点击即生成提示词</div></div>
238
- </div>
239
- <div class="grid" id="officeGrid" data-i18n="common.loading"><div class="empty">加载中…</div></div>
240
- </div>
241
-
242
- <!-- 节点管理页面 -->
243
- <div class="page-view" data-view="nodes">
244
- <div class="page-head">
245
- <div><h2>🔗 节点管理</h2><div class="sub">连接外部节点,扩展模板/插件/办公能力来源</div></div>
246
- <div class="row" style="flex:0 0 auto; gap:8px;">
247
- <button id="addNodeBtn">+ 添加节点</button>
248
- <button id="addSourceBtn" class="ghost">+ 自定义来源</button>
249
- </div>
250
- </div>
251
- <div class="section-title">已连接节点</div>
252
- <div class="grid" id="nodesGrid"><div class="empty">还没有添加节点,点击上方「添加节点」连接外部服务</div></div>
253
- <div class="section-title" style="margin-top:20px;">自定义来源</div>
254
- <div class="grid" id="sourcesGrid"><div class="empty">还没有自定义来源,点击上方「自定义来源」添加远程数据源</div></div>
255
- </div>
256
-
257
- <!-- 记忆系统页面 -->
258
- <div class="page-view" data-view="memory">
259
- <div class="page-head">
260
- <div data-i18n="nav.memory"><h2>🧠 记忆系统</h2><div class="sub">短期记忆每日自动整理,沉淀长期知识</div></div>
261
- <div class="row">
262
- <button id="memRefreshBtn" class="ghost" data-i18n="btn.refresh">🔄 刷新</button>
263
- <button id="memSummarizeBtn" data-i18n="btn.summarize">✨ 立即总结</button>
264
- </div>
265
- </div>
266
-
267
- <!-- 统计卡片 -->
268
- <div class="memory-stats" id="memoryStats" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:12px;margin-bottom:20px;">
269
- <div class="card stat-card">
270
- <div class="stat-label" data-i18n="mem.stat_short_days">短期记忆天数</div>
271
- <div class="stat-value" id="statShortDays">-</div>
272
- </div>
273
- <div class="card stat-card">
274
- <div class="stat-label" data-i18n="mem.stat_long_items">长期记忆条目</div>
275
- <div class="stat-value" id="statLongNotes">-</div>
276
- </div>
277
- <div class="card stat-card">
278
- <div class="stat-label" data-i18n="mem.stat_last_summary">上次总结</div>
279
- <div class="stat-value stat-date" id="statLastSum">-</div>
280
- </div>
281
- <div class="card stat-card">
282
- <div class="stat-label" data-i18n="mem.stat_next_summary">下次自动总结</div>
283
- <div class="stat-value stat-date" id="statNextSum">-</div>
284
- </div>
285
- </div>
286
-
287
- <!-- Tab 切换 -->
288
- <div class="memory-tabs" style="display:flex;gap:8px;margin-bottom:16px;border-bottom:1px solid var(--border);padding-bottom:8px;">
289
- <button class="mem-tab active" data-memtab="short" style="padding:6px 14px;border-radius:8px;border:1px solid var(--border);background:var(--card);cursor:pointer;font-size:13px;" data-i18n="mem.tab_short">📅 短期记忆</button>
290
- <button class="mem-tab" data-memtab="long" style="padding:6px 14px;border-radius:8px;border:1px solid var(--border);background:var(--card);cursor:pointer;font-size:13px;" data-i18n="mem.tab_long">💾 长期记忆</button>
291
- <button class="mem-tab" data-memtab="history" style="padding:6px 14px;border-radius:8px;border:1px solid var(--border);background:var(--card);cursor:pointer;font-size:13px;" data-i18n="mem.tab_history">📜 总结历史</button>
292
- </div>
293
-
294
- <!-- 短期记忆面板 -->
295
- <div class="mem-panel active" id="memShortPanel">
296
- <div class="row" style="margin-bottom:16px;align-items:center;">
297
- <input type="date" id="memDateInput" style="margin:0;width:160px;" />
298
- <button id="memLoadDay" style="margin:0;" data-i18n="btn.view">查看</button>
299
- <button id="memAddShort" style="margin:0;" class="ghost">+ 添加记录</button>
300
- <span class="muted" id="memDateLabel" style="margin-left:8px;"></span>
301
- </div>
302
- <!-- 添加记录文本框(默认隐藏,点击添加记录后展开) -->
303
- <div id="memShortEditor" style="display:none;margin-bottom:16px;padding:12px;border:1px solid var(--border);border-radius:8px;background:var(--bg);">
304
- <textarea id="memShortInput" rows="4" placeholder="直接输入你想记录的内容,点击保存即可添加到今天的短期记忆..." style="width:100%;padding:10px;border:1px solid var(--border);border-radius:6px;background:var(--card);color:var(--ink);font-size:13px;resize:vertical;box-sizing:border-box;"></textarea>
305
- <div style="margin-top:8px;display:flex;gap:8px;justify-content:flex-end;">
306
- <button id="memShortCancel" class="ghost">取消</button>
307
- <button id="memShortSave" class="primary">保存</button>
308
- </div>
309
- </div>
310
- <div class="card memory-content" id="memShortContent">
311
- <div class="empty" data-i18n="btn.view">选择日期查看短期记忆</div>
312
- </div>
313
- </div>
314
-
315
- <!-- 长期记忆面板 -->
316
- <div class="mem-panel" id="memLongPanel" style="display:none;">
317
- <div class="row" style="margin-bottom:16px;align-items:center;">
318
- <button id="memEditLong" style="margin:0;">✎ 编辑</button>
319
- <button id="memSaveLong" style="margin:0;display:none;" class="primary">💾 保存</button>
320
- <button id="memCancelLong" style="margin:0;display:none;" class="ghost">取消</button>
321
- <button id="memAppendLong" style="margin:0;" class="ghost">+ 追加</button>
322
- <span class="muted" style="margin-left:8px;">长期记忆会在对话中被 AI 参考</span>
323
- </div>
324
- <!-- 追加条目文本框(默认隐藏) -->
325
- <div id="memLongAppendEditor" style="display:none;margin-bottom:16px;padding:12px;border:1px solid var(--border);border-radius:8px;background:var(--bg);">
326
- <input type="text" id="memAppendTitle" placeholder="条目标题(如:项目知识/用户偏好)" style="width:100%;padding:8px 10px;border:1px solid var(--border);border-radius:6px;background:var(--card);color:var(--ink);font-size:13px;margin-bottom:8px;box-sizing:border-box;" />
327
- <textarea id="memAppendContent" rows="3" placeholder="输入你想追加的记忆内容..." style="width:100%;padding:10px;border:1px solid var(--border);border-radius:6px;background:var(--card);color:var(--ink);font-size:13px;resize:vertical;box-sizing:border-box;"></textarea>
328
- <div style="margin-top:8px;display:flex;gap:8px;justify-content:flex-end;">
329
- <button id="memAppendCancel" class="ghost">取消</button>
330
- <button id="memAppendSave" class="primary">追加</button>
331
- </div>
332
- </div>
333
- <div class="card memory-content" id="memLongContent">
334
- <div class="empty" data-i18n="common.loading">加载中…</div>
335
- </div>
336
- <textarea id="memLongEditor" style="display:none;width:100%;min-height:400px;padding:12px;border:1px solid var(--border);border-radius:8px;background:var(--bg);color:var(--ink);font-family:monospace;font-size:13px;resize:vertical;box-sizing:border-box;"></textarea>
337
- </div>
338
-
339
- <!-- 总结历史面板 -->
340
- <div class="mem-panel" id="memHistoryPanel" style="display:none;">
341
- <div class="card memory-content" id="memHistoryContent">
342
- <div class="empty" data-i18n="empty.no_history">暂无总结记录</div>
343
- </div>
344
- </div>
345
- </div>
346
-
347
- <!-- 产品发布故事页面 -->
348
- <div class="page-view" data-view="release">
349
- <div class="release-container">
350
- <!-- Hero Section -->
351
- <div class="release-hero">
352
- <div class="release-badge">v0.5.1</div>
353
- <h1 class="release-title">飞虹 Code</h1>
354
- <p class="release-subtitle">终端 AI 编程智能体 · 自我进化 · 企业级安全</p>
355
- <p class="release-tagline">三个人,三年,从零到一</p>
356
- <div class="release-stats">
357
- <div class="stat-item"><span class="stat-num">M0→M9.1</span><span class="stat-label">全功能里程碑</span></div>
358
- <div class="stat-item"><span class="stat-num">42+</span><span class="stat-label">单元测试</span></div>
359
- <div class="stat-item"><span class="stat-num">145</span><span class="stat-label">集成验证断言</span></div>
360
- <div class="stat-item"><span class="stat-num">MIT</span><span class="stat-label">开源许可证</span></div>
361
- </div>
362
- </div>
363
-
364
- <!-- Timeline Section -->
365
- <div class="release-timeline">
366
- <h2 class="section-title">三年历程</h2>
367
- <div class="timeline">
368
- <div class="timeline-item">
369
- <div class="timeline-dot"></div>
370
- <div class="timeline-content">
371
- <div class="timeline-date">2023 年 · 起点</div>
372
- <h3>三个开发者的初心</h3>
373
- <p>在泉州一家制造业AI服务公司的办公室里,三个开发者围着一台老旧的台式机,讨论着一个大胆的想法:做一个真正能自主写代码的AI助手。</p>
374
- <p class="timeline-quote">"为什么AI只能回答问题,而不能动手写代码?"</p>
375
- <div class="timeline-tags"><span class="tag">M0 脚手架</span><span class="tag">工程初始化</span></div>
376
- </div>
377
- </div>
378
-
379
- <div class="timeline-item">
380
- <div class="timeline-dot"></div>
381
- <div class="timeline-content">
382
- <div class="timeline-date">2024 年 · 探索</div>
383
- <h3>从 Mock 到真实模型</h3>
384
- <p>第一年,我们走了很多弯路。最初只能用 Mock 驱动,代码生成完全不可能。接入 DeepSeek、通义千问后,终于看到了希望。</p>
385
- <p class="timeline-quote">"每一次 API 超时都是一次教训,每一次报错都是成长的机会。"</p>
386
- <div class="timeline-tags"><span class="tag">M1 模型路由</span><span class="tag">M2 多代理</span></div>
387
- </div>
388
- </div>
389
-
390
- <div class="timeline-item">
391
- <div class="timeline-dot"></div>
392
- <div class="timeline-content">
393
- <div class="timeline-date">2025 年 · 突破</div>
394
- <h3>企业级能力与自我进化</h3>
395
- <p>第二年,客户需求倒逼我们做出企业级功能:RBAC权限、审计链、多租户隔离。同时,我们实现了自我进化——让AI从失败中学习。</p>
396
- <p class="timeline-quote">"一个不会自我修复的AI,只是一个高级脚本。"</p>
397
- <div class="timeline-tags"><span class="tag">M3 会话恢复</span><span class="tag">M4 企业级</span><span class="tag">M6 自我进化</span></div>
398
- </div>
399
- </div>
400
-
401
- <div class="timeline-item">
402
- <div class="timeline-dot active"></div>
403
- <div class="timeline-content">
404
- <div class="timeline-date">2026 年 · 发布</div>
405
- <h3>v0.5.1 正式发布</h3>
406
- <p>经过上千次测试迭代,飞虹 Code 终于完成 M0→M9.1 全部里程碑。从离线演示到企业部署,从个人开发到团队协用。</p>
407
- <p class="timeline-quote">"这不仅是代码,是三年心血的结晶。"</p>
408
- <div class="timeline-tags"><span class="tag">M9 全自动 SWE Agent</span><span class="tag">Web 控制台</span><span class="tag">MIT 开源</span></div>
409
- </div>
410
- </div>
411
- </div>
412
- </div>
413
-
414
- <!-- Team Section -->
415
- <div class="release-team">
416
- <h2 class="section-title">核心团队</h2>
417
- <div class="team-grid">
418
- <div class="team-card">
419
- <div class="team-avatar">👨‍💻</div>
420
- <h3>架构师</h3>
421
- <p>负责整体架构设计,选型 TypeScript + Node.js,搭建工程体系。</p>
422
- <div class="team-role">首席架构师</div>
423
- </div>
424
- <div class="team-card">
425
- <div class="team-avatar">👩‍💻</div>
426
- <h3>算法工程师</h3>
427
- <p>主攻模型路由策略,实现多模型自动选优与降级机制。</p>
428
- <div class="team-role">AI 算法工程师</div>
429
- </div>
430
- <div class="team-card">
431
- <div class="team-avatar">🧑‍💻</div>
432
- <h3>后端开发</h3>
433
- <p>负责企业级安全模块,RBAC、审计链、多租户隔离的核心实现。</p>
434
- <div class="team-role">后端安全工程师</div>
435
- </div>
436
- </div>
437
- </div>
438
-
439
- <!-- Challenges Section -->
440
- <div class="release-challenges">
441
- <h2 class="section-title">走过的坑</h2>
442
- <div class="challenges-list">
443
- <div class="challenge-item">
444
- <span class="challenge-icon">🔥</span>
445
- <div>
446
- <h4>并发控制难题</h4>
447
- <p>多代理并行时,API 限流导致大量 429 错误。解决方案:引入队列机制 + 指数退避重试。</p>
448
- </div>
449
- </div>
450
- <div class="challenge-item">
451
- <span class="challenge-icon">🔒</span>
452
- <div>
453
- <h4>企业安全合规</h4>
454
- <p>客户要求审计链不可篡改。解决方案:实现 SHA-256 哈希链,每次写入强制追加。</p>
455
- </div>
456
- </div>
457
- <div class="challenge-item">
458
- <span class="challenge-icon">🧠</span>
459
- <div>
460
- <h4>上下文管理</h4>
461
- <p>长对话超出 Token 限制。解决方案:实现智能压缩算法,保留关键信息+摘要早期内容。</p>
462
- </div>
463
- </div>
464
- </div>
465
- </div>
466
-
467
- <!-- Features Section -->
468
- <div class="release-features">
469
- <h2 class="section-title">核心能力</h2>
470
- <div class="features-grid">
471
- <div class="feature-card">
472
- <div class="feature-icon">🔄</div>
473
- <h4>自我进化</h4>
474
- <p>记录失败 学习经验 → 自动应用</p>
475
- </div>
476
- <div class="feature-card">
477
- <div class="feature-icon">🛡️</div>
478
- <h4>企业级安全</h4>
479
- <p>RBAC + 审计链 + 多租户隔离</p>
480
- </div>
481
- <div class="feature-card">
482
- <div class="feature-icon">🌐</div>
483
- <h4>多模型路由</h4>
484
- <p>DeepSeek / 通义 / Ollama / OpenAI</p>
485
- </div>
486
- <div class="feature-card">
487
- <div class="feature-icon">⚡</div>
488
- <h4>离线可用</h4>
489
- <p>本地 Ollama 支持,数据不出内网</p>
490
- </div>
491
- <div class="feature-card">
492
- <div class="feature-icon">🔧</div>
493
- <h4>SWE Agent</h4>
494
- <p>全自动软件工程,读仓→拆解→实现→验证</p>
495
- </div>
496
- <div class="feature-card">
497
- <div class="feature-icon">💬</div>
498
- <h4>Web 控制台</h4>
499
- <p>浏览器管理界面,可视化任务与审计</p>
500
- </div>
501
- </div>
502
- </div>
503
-
504
- <!-- Quote Section -->
505
- <div class="release-quote">
506
- <blockquote>"从三个人的小团队,到如今服务百余家制造业企业,飞虹 Code 见证了我们三年的坚持。我们相信,开源是最好的传播方式。"</blockquote>
507
- <cite>— 吴赐虹,飞扬企源研发中心负责人</cite>
508
- </div>
509
-
510
- <!-- CTA Section -->
511
- <div class="release-cta">
512
- <h2>开始使用飞虹 Code</h2>
513
- <div class="cta-buttons">
514
- <a href="https://github.com/wch887292/feihong-code" target="_blank" class="cta-btn primary">⭐ GitHub Star</a>
515
- <a href="https://www.npmjs.com/package/feihong-code" target="_blank" class="cta-btn secondary">📦 npm install</a>
516
- </div>
517
- <p class="cta-sub">MIT 开源 · 晋江市飞虹智科技企业管理有限公司 · 飞扬企源研发中心</p>
518
- </div>
519
- </div>
520
- </div>
521
-
522
- <!-- 底部工具栏 -->
523
- <div class="chat-footbar" id="chatFootbar">
524
- <div data-i18n="sidebar.chat"><strong>对话任务</strong><span class="muted"> · 提交自然语言需求,云端静默执行并回传结果</span></div>
525
- <div class="row" style="flex:0 0 auto; gap:8px; align-items:center;">
526
- <label class="model-label" for="modelSelect" data-i18n="footbar.model">大模型</label>
527
- <select id="modelSelect" class="model-select" title="切换当前使用的大模型" data-i18n="footbar.model">
528
- <option value="" data-i18n="footbar.model_default">默认(系统路由)</option>
529
- </select>
530
- <button id="modelSettingsShortcut" class="ghost-btn" title="大模型设置" data-i18n="sidebar.settings">🧠</button>
531
- </div>
532
- </div>
533
- <!-- 视频通话窗口 -->
534
- <div class="video-call-window" id="videoCallWindow" style="display:none;">
535
- <div class="video-call-header">
536
- <span>📹 视频通话中</span>
537
- <div style="display:flex;gap:8px;align-items:center;">
538
- <button class="video-call-snapshot" id="videoSnapshotBtn" title="截取当前画面发送">📸</button>
539
- <button class="video-call-close" id="videoCallClose">✕</button>
540
- </div>
541
- </div>
542
- <video id="localVideo" autoplay muted playsinline></video>
543
- </div>
544
- </main>
545
-
546
- <!-- 右侧面板 -->
547
- <aside class="right-panel" id="rightPanel">
548
- <div class="right-tabs">
549
- <div class="right-tab active" data-tab="detail" data-i18n="right.detail">📦 任务详情</div>
550
- <div class="right-tab" data-tab="preview" data-i18n="right.preview">👁 产物预览</div>
551
- <div class="right-tab" data-tab="computer" id="computerTab" style="display:none;">🖥 电脑操作</div>
552
- </div>
553
- <div class="right-body">
554
- <div class="preview-panel active" id="detailPanel">
555
- <div id="taskDetail" data-i18n="btn.view"><div class="muted">从顶部选择一个任务查看详情。</div></div>
556
- </div>
557
- <div class="preview-panel" id="previewPanel">
558
- <div class="preview-title" id="previewTitle" data-i18n="right.preview_title">预览</div>
559
- <div class="preview-content" id="previewContent" data-i18n="right.preview_title"><div class="muted">点击任务或对话中的文件/代码进行预览。</div></div>
560
- </div>
561
- <div class="preview-panel" id="computerPanel">
562
- <div class="computer-controls">
563
- <button id="screenCaptureBtn" class="pill">📷 截取屏幕</button>
564
- <span id="mousePos" class="muted" style="font-size:12px;">坐标: -</span>
565
- </div>
566
- <div class="screen-preview" id="screenPreview">
567
- <div class="muted" style="text-align:center;padding:40px;">点击「截取屏幕」查看当前屏幕</div>
568
- </div>
569
- <div class="computer-actions">
570
- <div style="margin-bottom:8px;font-size:13px;font-weight:600;">快捷操作</div>
571
- <div style="display:flex;gap:6px;flex-wrap:wrap;margin-bottom:10px;">
572
- <button class="pill" id="clickLeftBtn">左键点击</button>
573
- <button class="pill" id="clickRightBtn">右键点击</button>
574
- <button class="pill" id="doubleClickBtn">双击</button>
575
- </div>
576
- <div style="margin-bottom:8px;">
577
- <input type="text" id="typeTextInput" placeholder="输入文字后回车发送" style="width:100%;padding:6px 8px;font-size:12px;border:1px solid var(--border);border-radius:6px;" />
578
- </div>
579
- <div style="display:flex;gap:6px;flex-wrap:wrap;">
580
- <button class="pill" data-key="{ENTER}">回车</button>
581
- <button class="pill" data-key="{TAB}">Tab</button>
582
- <button class="pill" data-key="{ESC}">Esc</button>
583
- <button class="pill" data-key="^c">复制</button>
584
- <button class="pill" data-key="^v">粘贴</button>
585
- <button class="pill" data-key="^a">全选</button>
586
- </div>
587
- </div>
588
- </div>
589
- </div>
590
- </aside>
591
- </div>
592
- </div>
593
-
594
- <!-- 模态框区域 -->
595
- <div class="mask" id="autoModal">
596
- <div class="modal">
597
- <span class="close-x" data-close="autoModal">✕</span>
598
- <h3 data-i18n="modal.auto_title">新建快捷指令</h3>
599
- <p class="hint" data-i18n="sidebar.automations">保存后可在「自动化」页一键发起任务。</p>
600
- <label for="autoName" data-i18n="modal.auto_name">指令名称</label>
601
- <input type="text" id="autoName" placeholder="如:每日构建检查" data-i18n="modal.auto_name_ph" />
602
- <label for="autoGoal" data-i18n="modal.auto_goal">目标(提交给模型的需求)</label>
603
- <textarea id="autoGoal" placeholder="运行 npm test 并汇总失败用例…" data-i18n="modal.auto_goal_ph"></textarea>
604
- <div class="footer">
605
- <button class="ghost" data-close="autoModal" data-i18n="btn.cancel">取消</button>
606
- <button id="autoSaveBtn" data-i18n="btn.save">保存</button>
607
- </div>
608
- </div>
609
- </div>
610
-
611
- <!-- 添加节点模态框 -->
612
- <div class="mask" id="nodeModal">
613
- <div class="modal">
614
- <span class="close-x" data-close="nodeModal">✕</span>
615
- <h3 id="nodeModalTitle">添加节点</h3>
616
- <p class="hint">连接外部节点,扩展模板/插件/办公能力来源。节点需提供标准 API 或本地 JSON 文件。</p>
617
- <input type="hidden" id="nodeEditId" />
618
- <label for="nodeName">节点名称</label>
619
- <input type="text" id="nodeName" placeholder="如:公司内部技能库" />
620
- <label for="nodeType">节点类型</label>
621
- <select id="nodeType">
622
- <option value="http">HTTP API 节点</option>
623
- <option value="local">本地目录节点</option>
624
- <option value="git">Git 仓库节点</option>
625
- </select>
626
- <label for="nodeUrl">地址(URL 或本地路径)</label>
627
- <input type="text" id="nodeUrl" placeholder="如:https://api.example.com 或 D:\nodes\my-node" />
628
- <label for="nodeApiKey">API Key(可选)</label>
629
- <input type="password" id="nodeApiKey" placeholder="留空表示不需要认证" autocomplete="off" />
630
- <label>提供的能力</label>
631
- <div style="display:flex;gap:16px;margin-bottom:12px;">
632
- <label style="display:flex;align-items:center;gap:6px;cursor:pointer;"><input type="checkbox" id="nodeCapTemplates" checked /> 模板</label>
633
- <label style="display:flex;align-items:center;gap:6px;cursor:pointer;"><input type="checkbox" id="nodeCapSkills" checked /> 插件</label>
634
- <label style="display:flex;align-items:center;gap:6px;cursor:pointer;"><input type="checkbox" id="nodeCapOffice" checked /> 办公</label>
635
- </div>
636
- <div class="footer">
637
- <button class="ghost" data-close="nodeModal">取消</button>
638
- <button id="nodeSaveBtn" class="primary">保存并测试连接</button>
639
- </div>
640
- </div>
641
- </div>
642
-
643
- <!-- 添加自定义来源模态框 -->
644
- <div class="mask" id="sourceModal">
645
- <div class="modal">
646
- <span class="close-x" data-close="sourceModal">✕</span>
647
- <h3 id="sourceModalTitle">添加自定义来源</h3>
648
- <p class="hint">添加远程 JSON 数据源,自动拉取模板/插件/办公能力。</p>
649
- <input type="hidden" id="sourceEditId" />
650
- <label for="sourceName">来源名称</label>
651
- <input type="text" id="sourceName" placeholder="如:团队共享模板" />
652
- <label for="sourceType">来源类型</label>
653
- <select id="sourceType">
654
- <option value="templates">模板</option>
655
- <option value="skills">插件</option>
656
- <option value="office">办公能力</option>
657
- </select>
658
- <label for="sourceUrl">JSON 数据地址</label>
659
- <input type="text" id="sourceUrl" placeholder="https://example.com/templates.json" />
660
- <div class="footer">
661
- <button class="ghost" data-close="sourceModal">取消</button>
662
- <button id="sourceSaveBtn" class="primary">保存</button>
663
- </div>
664
- </div>
665
- </div>
666
-
667
- <div class="mask" id="tplModal">
668
- <div class="modal">
669
- <span class="close-x" data-close="tplModal">✕</span>
670
- <h3 data-i18n="btn.save">保存为模板</h3>
671
- <label for="tplTitle" data-i18n="modal.tpl_title_label">模板标题</label>
672
- <input type="text" id="tplTitle" placeholder="如:SQL 优化" data-i18n="modal.tpl_title_ph" />
673
- <label for="tplCategory" data-i18n="modal.tpl_category">分类</label>
674
- <input type="text" id="tplCategory" placeholder="自定义" data-i18n="modal.tpl_category_ph" />
675
- <label for="tplGoal" data-i18n="modal.tpl_goal">目标内容</label>
676
- <textarea id="tplGoal" placeholder="粘贴要保存的需求文本…" data-i18n="btn.save"></textarea>
677
- <div class="footer">
678
- <button class="ghost" data-close="tplModal" data-i18n="btn.cancel">取消</button>
679
- <button id="tplSaveBtn" data-i18n="btn.save">保存</button>
680
- </div>
681
- </div>
682
- </div>
683
-
684
- <div class="mask" id="permModal">
685
- <div class="modal" style="width:480px;">
686
- <span class="close-x" data-close="permModal">✕</span>
687
- <h3 data-i18n="modal.perm_title">🔒 权限处理窗口</h3>
688
- <p class="hint" data-i18n="modal.perm_hint">配置工作期间 AI 可读范围及可操作权限。</p>
689
- <div class="perm-section">
690
- <div class="perm-title" data-i18n="modal.perm_read_scope">可读范围</div>
691
- <div class="perm-row">
692
- <input type="radio" name="readScope" id="scopeWorkspace" value="workspace" checked />
693
- <label for="scopeWorkspace" data-i18n="modal.perm_workspace">仅当前工作区</label>
694
- </div>
695
- <div class="perm-row">
696
- <input type="radio" name="readScope" id="scopeSpecified" value="specified" />
697
- <label for="scopeSpecified" data-i18n="modal.perm_specified">指定目录</label>
698
- </div>
699
- <div class="perm-row">
700
- <input type="text" id="permReadPath" placeholder="输入允许的目录路径" style="margin:0;" data-i18n="modal.perm_path_ph" />
701
- </div>
702
- <div class="perm-row">
703
- <input type="radio" name="readScope" id="scopeAll" value="all" />
704
- <label for="scopeAll" data-i18n="modal.perm_all">全部文件</label>
705
- </div>
706
- </div>
707
- <div class="perm-section">
708
- <div class="perm-title" data-i18n="modal.perm_actions">操作权限</div>
709
- <div class="perm-row">
710
- <input type="checkbox" id="permRead" checked />
711
- <label for="permRead" data-i18n="modal.perm_read">读取文件</label>
712
- </div>
713
- <div class="perm-row">
714
- <input type="checkbox" id="permWrite" />
715
- <label for="permWrite" data-i18n="modal.perm_write">写入文件</label>
716
- </div>
717
- <div class="perm-row">
718
- <input type="checkbox" id="permShell" />
719
- <label for="permShell" data-i18n="modal.perm_shell">执行命令</label>
720
- </div>
721
- <div class="perm-row">
722
- <input type="checkbox" id="permNetwork" checked />
723
- <label for="permNetwork" data-i18n="modal.perm_network">访问网络</label>
724
- </div>
725
- <div class="perm-row">
726
- <input type="checkbox" id="permBrowser" />
727
- <label for="permBrowser" data-i18n="modal.perm_browser">浏览器控制</label>
728
- </div>
729
- </div>
730
- <div class="footer">
731
- <button class="ghost" data-close="permModal" data-i18n="btn.cancel">取消</button>
732
- <button id="permSaveBtn" data-i18n="btn.save">保存</button>
733
- </div>
734
- </div>
735
- </div>
736
-
737
- <div class="mask" id="agentModal">
738
- <div class="modal" style="width:420px;">
739
- <span class="close-x" data-close="agentModal">✕</span>
740
- <h3 data-i18n="chat.agent_type">🤖 选择智能体类型</h3>
741
- <p class="hint" data-i18n="modal.agent_hint">不同智能体会自动调整提示词与执行策略。</p>
742
- <div class="agent-grid" id="agentGrid"></div>
743
- <div class="footer">
744
- <button class="ghost" data-close="agentModal" data-i18n="btn.cancel">取消</button>
745
- </div>
746
- </div>
747
- </div>
748
-
749
- <div class="crop-overlay" id="cropOverlay" style="display:none;">
750
- <div class="crop-tip" id="cropTip" data-i18n="crop.tip">按住鼠标拖拽选择截图区域 · 松开确认 · ESC 取消</div>
751
- <div class="crop-selection" id="cropSelection"></div>
752
- <video id="cropVideo" style="display:none;"></video>
753
- </div>
754
-
755
- <div class="mask" id="folderPickerModal">
756
- <div class="modal" style="width:560px;">
757
- <span class="close-x" data-close="folderPickerModal">✕</span>
758
- <h3 id="fpTitle">📂 选择工作区文件夹</h3>
759
-
760
- <!-- 驱动器选择视图 -->
761
- <div id="fpDrivesView">
762
- <p class="hint" style="margin:8px 0;">请选择一个驱动器,然后在其中选择或新建文件夹作为工作区。</p>
763
- <div class="fp-drives-grid" id="fpDrivesGrid" style="display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin:10px 0;max-height:320px;overflow:auto;"></div>
764
- </div>
765
-
766
- <!-- 文件夹选择视图 -->
767
- <div id="fpFoldersView" style="display:none;">
768
- <div style="display:flex;align-items:center;gap:8px;margin-bottom:8px;">
769
- <button class="ghost sm" id="fpBackToDrives" style="flex-shrink:0;">← 驱动器</button>
770
- <button class="ghost sm" id="fpUpDir" style="flex-shrink:0;">↑ 上级</button>
771
- <div class="fp-path" id="fpPath" style="flex:1;font-size:12px;color:var(--ink-2);word-break:break-all;padding:6px 8px;background:var(--bg);border-radius:6px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">—</div>
772
- </div>
773
- <div style="display:flex;gap:8px;margin-bottom:8px;">
774
- <button class="ghost sm" id="fpNewFolder">+ 新建文件夹</button>
775
- <button class="ghost sm" id="fpRenameFolder" disabled>✎ 重命名</button>
776
- </div>
777
- <div class="file-tree" id="fpTree" style="max-height:260px;overflow:auto;margin:10px 0;"></div>
778
- </div>
779
-
780
- <!-- 新建文件夹输入框 -->
781
- <div id="fpMkdirBar" style="display:none;gap:8px;margin-bottom:8px;">
782
- <input type="text" id="fpMkdirName" placeholder="输入新文件夹名称" style="flex:1;padding:6px 10px;border:1px solid var(--line);border-radius:6px;font-size:13px;" />
783
- <button class="primary sm" id="fpMkdirConfirm">确定</button>
784
- <button class="ghost sm" id="fpMkdirCancel">取消</button>
785
- </div>
786
-
787
- <!-- 重命名输入框 -->
788
- <div id="fpRenameBar" style="display:none;gap:8px;margin-bottom:8px;">
789
- <input type="text" id="fpRenameName" placeholder="输入新名称" style="flex:1;padding:6px 10px;border:1px solid var(--line);border-radius:6px;font-size:13px;" />
790
- <button class="primary sm" id="fpRenameConfirm">确定</button>
791
- <button class="ghost sm" id="fpRenameCancel">取消</button>
792
- </div>
793
-
794
- <div class="footer">
795
- <button class="ghost" id="fpCancel" data-close="folderPickerModal">取消</button>
796
- <button class="primary" id="fpConfirm" disabled>选择此文件夹</button>
797
- </div>
798
- </div>
799
- </div>
800
-
801
- <div class="mask" id="modelModal">
802
- <div class="modal" style="width:520px;">
803
- <span class="close-x" data-close="modelModal">✕</span>
804
- <h3 data-i18n="sidebar.settings">🧠 大模型设置</h3>
805
- <p class="hint" data-i18n="footbar.model">配置自定义大模型,可保存多个并在对话中随时切换。勾选「默认」的项将作为对话默认模型。</p>
806
- <div class="model-list" id="modelList"></div>
807
- <div class="model-form">
808
- <div class="form-row">
809
- <div class="form-field">
810
- <label data-i18n="modal.model_name">模型名称 *</label>
811
- <input type="text" id="modelName" placeholder="如 GPT-4o / 通义千问 / 自建模型" data-i18n="modal.model_name_ph" />
812
- </div>
813
- <div class="form-field">
814
- <label data-i18n="modal.model_api">API 地址</label>
815
- <input type="text" id="modelApiBase" placeholder="https://api.openai.com/v1" data-i18n="modal.model_api_ph" />
816
- </div>
817
- </div>
818
- <div class="form-field">
819
- <label data-i18n="modal.model_key">密钥(API Key)</label>
820
- <input type="password" id="modelApiKey" placeholder="sk-..." autocomplete="off" data-i18n="modal.model_key_ph" />
821
- </div>
822
- <div class="form-field">
823
- <label data-i18n="modal.model_reasoning">推理过程运行内容(中间环节)</label>
824
- <textarea id="modelReasoning" rows="3" placeholder="配置该模型在中间推理环节的运行内容,例如:先列出需求拆解,再给出实现方案,最后输出代码。" data-i18n="modal.model_reasoning_ph"></textarea>
825
- </div>
826
- <div class="form-actions">
827
- <button id="modelSaveBtn" class="primary" data-i18n="btn.save">保存配置</button>
828
- <button id="modelResetBtn" class="ghost" data-i18n="btn.clear_form">清空表单</button>
829
- <span id="modelFormMsg" class="model-form-msg"></span>
830
- </div>
831
- </div>
832
- <div class="footer">
833
- <button class="ghost" data-close="modelModal" data-i18n="btn.close">关闭</button>
834
- </div>
835
- </div>
836
- </div>
837
-
838
- <div class="mask" id="newTaskModal">
839
- <div class="modal" style="width:560px;">
840
- <span class="close-x" data-close="newTaskModal">✕</span>
841
- <h3 data-i18n="sidebar.chat">+ 新建对话任务</h3>
842
- <p class="hint" data-i18n="modal.new_task_hint">创建一个全新任务,中部对话栏的所有消息都将归属该任务运行(支持多轮连续对话)。</p>
843
- <div class="nt-form">
844
- <label class="nt-label" data-i18n="modal.new_task_label">任务描述 <span style="color:var(--err)">*</span></label>
845
- <textarea id="ntGoal" rows="5" placeholder="例如:请读取当前工作区 package.json,告诉我其中的 name 与 version 字段" data-i18n="modal.new_task_workspace"></textarea>
846
- <div class="nt-row">
847
- <div>
848
- <label class="nt-label" data-i18n="modal.new_task_agent">智能体类型</label>
849
- <select id="ntAgentType"></select>
850
- </div>
851
- <div>
852
- <label class="nt-label" data-i18n="modal.new_task_workspace">工作区</label>
853
- <select id="ntWorkspaceDir"></select>
854
- </div>
855
- </div>
856
- <div class="nt-hint" data-i18n="modal.new_task_workspace">工作区默认使用底部当前所选目录;若选择「默认」,则沿用服务器工作区。</div>
857
- </div>
858
- <div class="footer">
859
- <button class="ghost" data-close="newTaskModal" data-i18n="btn.cancel">取消</button>
860
- <button class="primary" id="ntCreateBtn" data-i18n="btn.create_task">创建任务</button>
861
- </div>
862
- </div>
863
- </div>
864
-
865
- <div class="mask" id="settingsModal">
866
- <div class="modal" style="width:560px;">
867
- <span class="close-x" data-close="settingsModal">✕</span>
868
- <h3 data-i18n="sidebar.settings">⚙️ 设置</h3>
869
- <div class="settings-layout">
870
- <div class="settings-nav">
871
- <div class="settings-cat active" data-cat="general" data-i18n="settings.general">通用</div>
872
- <div class="settings-cat" data-cat="internal" data-i18n="settings.layout">栏目配置</div>
873
- </div>
874
- <div class="settings-body" id="settingsBody">
875
- <div class="settings-group" data-group="general">
876
- <div class="settings-item" data-action="perm">
877
- <span class="si-icon">🔒</span>
878
- <div class="si-main" data-i18n="modal.perm_read_scope"><div class="si-title">权限处理</div><div class="si-desc">配置工作期间可读范围与操作权限</div></div>
879
- <span class="si-arrow">›</span>
880
- </div>
881
- <div class="settings-item" data-action="theme">
882
- <span class="si-icon">🎨</span>
883
- <div class="si-main" data-i18n="settings.theme"><div class="si-title">外观</div><div class="si-desc">切换浅色 / 深色主题</div></div>
884
- <span class="si-arrow">›</span>
885
- </div>
886
- <hr style="border:none;border-top:1px solid var(--line);margin:8px 0;">
887
- <div style="padding:8px 0;">
888
- <div style="font-weight:600;font-size:13px;color:var(--ink);margin-bottom:8px;" data-i18n="settings.session">💬 会话管理</div>
889
- <div style="display:flex;flex-direction:column;gap:8px;">
890
- <label style="display:flex;align-items:center;gap:8px;font-size:13px;cursor:pointer;">
891
- <input type="checkbox" class="session-toggle" data-key="autoResetOnNew">
892
- <span data-i18n="settings.session_auto_new">发送消息前自动新建对话</span>
893
- </label>
894
- <label style="display:flex;align-items:center;gap:8px;font-size:13px;cursor:pointer;">
895
- <input type="checkbox" class="session-toggle" data-key="autoResetOnOpen">
896
- <span data-i18n="settings.session_auto_open">页面打开时自动新建对话</span>
897
- </label>
898
- <label style="display:flex;align-items:center;gap:8px;font-size:13px;cursor:pointer;">
899
- <input type="checkbox" class="session-toggle" data-key="clearHistoryOnNew">
900
- <span data-i18n="settings.session_clear">新建对话时清空历史上下文</span>
901
- </label>
902
- </div>
903
- </div>
904
- </div>
905
- <div class="settings-group" data-group="internal" style="display:none;">
906
- <div class="settings-item" data-action="model-custom" id="modelCustomItem">
907
- <span class="si-icon">🧠</span>
908
- <div class="si-main">
909
- <div class="si-title" data-i18n="sidebar.settings">大模型自定义设置</div>
910
- <div class="si-desc" data-i18n="footbar.model">自由添加并配置自定义大模型,提供大模型选择列表,可设为默认</div>
911
- </div>
912
- <span class="si-arrow">›</span>
913
- </div>
914
- <div class="model-manage" id="modelManage" style="display:none;">
915
- <div class="mm-list" id="modelListInline"></div>
916
- <div class="mm-divider"><span>添加新模型</span></div>
917
- <div class="mm-form">
918
- <div class="mm-form-title">填写模型信息</div>
919
- <input type="text" id="imName" placeholder="模型名称(必填)" data-i18n="modal.model_name" />
920
- <input type="text" id="imBase" placeholder="API 地址(如 https://api.openai.com/v1)" data-i18n="modal.model_api" />
921
- <input type="password" id="imKey" placeholder="API Key(编辑时留空保留原值)" autocomplete="off" />
922
- <textarea id="imReasoning" rows="2" placeholder="推理中间环节内容(可选)"></textarea>
923
- <div class="mm-form-actions">
924
- <button id="imSave" class="primary sm" data-i18n="btn.save">保存</button>
925
- <button id="imReset" class="ghost sm">清空</button>
926
- <span id="imMsg" class="mm-form-msg"></span>
927
- </div>
928
- </div>
929
- </div>
930
- </div>
931
- </div>
932
- </div>
933
- <div class="footer">
934
- <button class="ghost" data-close="settingsModal" data-i18n="btn.close">关闭</button>
935
- </div>
936
- </div>
937
- </div>
938
-
939
- <div class="bottom-sheet-mask" id="userMenuMask">
940
- <div class="bottom-sheet" id="userMenu">
941
- <div class="sheet-header">
942
- <div class="topbar-avatar" style="width:40px;height:40px;border-radius:50%;background:var(--brand-soft);display:flex;align-items:center;justify-content:center;font-size:20px;">🦐</div>
943
- <div>
944
- <div class="topbar-phone" id="sheetPhone">未登录</div>
945
- <div class="muted">免费版</div>
946
- </div>
947
- </div>
948
- <div class="sheet-item" data-action="version" data-i18n="menu.version"><span class="icon">🎖</span>体验版<span class="right">当前</span></div>
949
- <div class="sheet-item" data-action="buddy" data-i18n="menu.buddy"><span class="icon">⛽</span>Buddy 加油站</div>
950
- <div class="sheet-item" data-action="invite" data-i18n="menu.invite"><span class="icon">👥</span>去邀约<span class="right">最高得会员</span></div>
951
- <div class="sheet-item" data-action="points" data-i18n="menu.points"><span class="icon">💎</span>积分余额</div>
952
- <div class="sheet-item" data-action="growth" data-i18n="menu.growth"><span class="icon">🌱</span>成长计划<span class="right">连登有奖</span></div>
953
- <div class="sheet-item" data-action="settings" data-i18n="sidebar.settings"><span class="icon">⚙️</span>设置</div>
954
- <div class="sheet-item" data-action="theme" data-i18n="settings.theme"><span class="icon">🎨</span>外观</div>
955
- <div class="sheet-item" data-action="help" data-i18n="menu.help"><span class="icon">❓</span>帮助与反馈</div>
956
- <div class="sheet-item" data-action="update" data-i18n="menu.update"><span class="icon">🔄</span>检查更新</div>
957
- <div class="sheet-item" data-action="logout" data-i18n="menu.logout"><span class="icon">↩️</span>退出登录</div>
958
- </div>
959
- </div>
960
-
961
- <div class="mask" id="welcomeGuideModal">
962
- <div class="modal">
963
- <span class="close-x" data-close="welcomeGuideModal">✕</span>
964
- <div class="welcome-guide-header">
965
- <div class="icon">🎉</div>
966
- <div>
967
- <h3>欢迎使用飞虹 Code!</h3>
968
- <p>系统已为您准备了三个引导任务,帮助您快速上手</p>
969
- </div>
970
- </div>
971
- <div class="welcome-task-list" id="welcomeTaskList">
972
- <!-- 动态填充 -->
973
- </div>
974
- <div class="footer">
975
- <button class="ghost" data-close="welcomeGuideModal">稍后再说</button>
976
- <button class="primary" id="welcomeRunAllBtn">▶ 全部运行</button>
977
- </div>
978
- </div>
979
- </div>
980
-
981
- <input type="file" id="fileInput" />
982
- <input type="file" id="imageInput" accept="image/*" />
983
- <div class="toast" id="toast"></div>
984
-
985
- <script src="js/utils.js"></script>
986
- <script src="js/api.js"></script>
987
- <script src="js/ui.js"></script>
988
- <script src="js/app.js"></script>
989
- </body>
990
- </html>
1
+ <!DOCTYPE html>
2
+ <html lang="zh">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title data-i18n="app.title_login">飞虹 Code 控制台 / fhcode Console</title>
7
+ <link rel="stylesheet" href="css/style.css">
8
+ <!-- Monaco Editor AMD Loader(代码编辑器内核,VSCode 同款) -->
9
+ <script src="vendor/monaco/vs/loader.js"></script>
10
+ </head>
11
+ <body>
12
+ <!-- 后端服务断连提示横幅 -->
13
+ <div class="backend-offline-banner" id="backendOfflineBanner" style="display:none;">
14
+ <span class="bob-icon">⚠️</span>
15
+ <span class="bob-text" id="backendOfflineText">后端服务已断开,正在自动重连…</span>
16
+ <button class="bob-reconnect" id="backendReconnectBtn">立即重连</button>
17
+ </div>
18
+ <div id="loginOverlay">
19
+ <div class="login-card">
20
+ <h2 data-i18n="app.title_login">飞虹 Code 控制台</h2>
21
+ <p data-i18n="app.login_hint">请输入手机号码直接登录</p>
22
+ <label for="loginPhone" data-i18n="login.phone_label">手机号码</label>
23
+ <input type="text" id="loginPhone" autocomplete="off" placeholder="如 13800138000" />
24
+ <button id="loginBtn" data-i18n="login.btn_login">手机号登录</button>
25
+ <div class="login-status" id="loginStatus"></div>
26
+ </div>
27
+ </div>
28
+
29
+ <div class="app-layout" id="appLayout">
30
+ <!-- 顶部导航栏 -->
31
+ <header class="topbar">
32
+ <div class="topbar-brand">
33
+ <div class="logo">🦞</div>
34
+ <span data-i18n="app.brand">飞虹 Code</span>
35
+ </div>
36
+ <nav class="topbar-nav">
37
+ <div class="topbar-nav-item active" data-nav="chat" data-i18n="nav.chat">💬 对话</div>
38
+ <div class="topbar-nav-item" data-nav="automations" data-i18n="nav.automations">⚡ 自动化</div>
39
+ <div class="topbar-nav-item" data-nav="templates" data-i18n="nav.templates">📚 模板库</div>
40
+ <div class="topbar-nav-item" data-nav="market" data-i18n="nav.market">🧩 插件</div>
41
+ <div class="topbar-nav-item" data-nav="office" data-i18n="nav.office">📎 办公</div>
42
+ <div class="topbar-nav-item" data-nav="memory" data-i18n="nav.memory">🧠 记忆</div>
43
+ <div class="topbar-nav-item" data-nav="release" data-i18n="nav.release">🚀 发布</div>
44
+ </nav>
45
+ <div class="topbar-spacer"></div>
46
+ <div class="lang-switcher">
47
+ <button class="lang-btn active" data-lang="zh">中文</button>
48
+ <button class="lang-btn" data-lang="en">EN</button>
49
+ </div>
50
+ <div class="topbar-user" id="topbarUser">
51
+ <div class="topbar-avatar">🦐</div>
52
+ <span class="topbar-phone" id="topbarPhone">未登录</span>
53
+ </div>
54
+ </header>
55
+
56
+ <!-- 主体区 -->
57
+ <div class="main-area">
58
+ <!-- 左侧图标导航 -->
59
+ <aside class="sidebar">
60
+ <!-- 导航菜单 -->
61
+ <div class="sidebar-section">
62
+ <div class="sidebar-section-title" data-i18n="sidebar.nav">导航</div>
63
+ <div class="sidebar-icon active" data-nav="chat" title="对话任务" data-i18n="sidebar.chat">
64
+ <span class="icon">💬</span>
65
+ <span class="label" data-i18n="sidebar.chat">对话任务</span>
66
+ </div>
67
+ <div class="sidebar-icon" data-nav="automations" title="自动化" data-i18n="sidebar.automations">
68
+ <span class="icon">⚡</span>
69
+ <span class="label" data-i18n="sidebar.automations">自动化</span>
70
+ </div>
71
+ <div class="sidebar-icon" data-nav="templates" title="模板库" data-i18n="sidebar.templates">
72
+ <span class="icon">📚</span>
73
+ <span class="label" data-i18n="sidebar.templates">模板库</span>
74
+ </div>
75
+ <div class="sidebar-icon" data-nav="market" title="插件市场" data-i18n="sidebar.market">
76
+ <span class="icon">🧩</span>
77
+ <span class="label" data-i18n="sidebar.market">插件市场</span>
78
+ </div>
79
+ <div class="sidebar-icon" data-nav="office" title="办公助理" data-i18n="sidebar.office">
80
+ <span class="icon">📎</span>
81
+ <span class="label" data-i18n="sidebar.office">办公助理</span>
82
+ </div>
83
+ <div class="sidebar-icon" data-nav="nodes" title="节点管理" data-i18n="sidebar.nodes">
84
+ <span class="icon">🔗</span>
85
+ <span class="label" data-i18n="sidebar.nodes">节点管理</span>
86
+ </div>
87
+ <div class="sidebar-icon" data-nav="memory" title="记忆系统" data-i18n="sidebar.memory">
88
+ <span class="icon">🧠</span>
89
+ <span class="label" data-i18n="sidebar.memory">记忆系统</span>
90
+ </div>
91
+ <div class="sidebar-icon" data-nav="release" title="产品发布" data-i18n="sidebar.release">
92
+ <span class="icon">🚀</span>
93
+ <span class="label" data-i18n="sidebar.release">产品发布</span>
94
+ </div>
95
+ </div>
96
+
97
+ <!-- 任务列表 -->
98
+ <div class="sidebar-section" id="taskListSection" style="display:none;">
99
+ <div class="sidebar-section-title" style="display:flex;align-items:center;justify-content:space-between;">
100
+ <span data-i18n="sidebar.task_list">任务列表 <span class="badge" id="taskCountBadge" style="margin-left:4px;">0</span></span>
101
+ <button class="new-task-btn" id="newTaskBtn" title="新建对话任务" data-i18n="sidebar.chat">+ 新建任务</button>
102
+ </div>
103
+ <div id="taskListContainer" style="max-height:300px;overflow-y:auto;">
104
+ <div class="empty" style="font-size:11px;padding:8px;" data-i18n="empty.no_tasks">暂无任务</div>
105
+ </div>
106
+ </div>
107
+
108
+ <div class="sidebar-spacer"></div>
109
+
110
+ <!-- 用户和设置 -->
111
+ <div class="sidebar-section">
112
+ <div class="sidebar-icon" id="sidebarUser" title="用户菜单" data-i18n="sidebar.user">
113
+ <span class="icon">👤</span>
114
+ <span class="label" data-i18n="sidebar.user">用户</span>
115
+ </div>
116
+ <div class="sidebar-icon" id="sidebarSettings" title="设置" data-i18n="sidebar.settings">
117
+ <span class="icon">⚙️</span>
118
+ <span class="label" data-i18n="sidebar.settings">设置</span>
119
+ </div>
120
+ </div>
121
+ </aside>
122
+
123
+ <!-- 中间内容区 -->
124
+ <main class="chat-area" id="chatArea">
125
+ <!-- 任务上下文头部 -->
126
+ <div class="task-context-header" id="taskContextHeader">
127
+ <div class="tch-left">
128
+ <div class="tch-title" id="tchTitle" data-i18n="task.not_selected">未选择任务</div>
129
+ <div class="tch-sub" id="tchSub" data-i18n="sidebar.task_list">从左侧任务列表选择,或在下方输入指令发起新任务</div>
130
+ </div>
131
+ <div class="tch-right">
132
+ <button class="ghost-btn" id="tchNewTask" title="新建对话任务" data-i18n="sidebar.chat">+ 新建任务</button>
133
+ <span class="badge" id="tchStatus">—</span>
134
+ <span class="tch-time" id="tchTime"></span>
135
+ <button class="ghost-btn" id="tchStop" title="停止当前任务" style="display:none;">⏹ 停止</button>
136
+ <button class="ghost-btn" id="tchRefresh" title="刷新当前任务" data-i18n="task.refresh">⟳</button>
137
+ </div>
138
+ </div>
139
+
140
+ <!-- 对话视图 -->
141
+ <div class="conv view active" data-view="chat">
142
+ <div class="messages" id="messages">
143
+ <div class="msg sys" data-i18n="btn.new_task">点击「+ 新建任务」开启一个新任务,或直接在下方向当前任务发送消息——所有对话都会归属同一个任务运行。</div>
144
+ </div>
145
+
146
+ <div class="input-area">
147
+ <div class="input-bar">
148
+ <div class="staged-area" id="stagedArea"></div>
149
+ <textarea id="goalInput" placeholder="输入指令,消息将归属当前任务持续对话;点上方「+ 新建任务」可开启新任务(创建 → 推理 → 工具验证 → 闭环全程追踪)" data-i18n="btn.new_task"></textarea>
150
+ <div class="input-toolbar">
151
+ <div class="dropdown" id="convMenuWrap">
152
+ <span class="pill" id="convMenuBtn" title="更多操作" data-i18n="chat.menu">+ 菜单</span>
153
+ <div class="dropdown-menu" id="convMenu">
154
+ <div class="dropdown-item" data-action="screenshot" data-i18n="chat.screenshot">📷 截图</div>
155
+ <div class="dropdown-item" data-action="upload-file" data-i18n="chat.upload_file">📄 上传文件</div>
156
+ <div class="dropdown-item" data-action="upload-image" data-i18n="chat.upload_image">🖼 上传图片</div>
157
+ <div class="dropdown-item" data-action="direct-mode" data-i18n="chat.direct_mode">🖥 电脑操作</div>
158
+ <div class="dropdown-item" data-action="voice" data-i18n="chat.voice">🎤 语音输入</div>
159
+ <div class="dropdown-divider"></div>
160
+ <div class="dropdown-item" data-action="agent-type" data-i18n="chat.agent_type">🤖 选择智能体类型</div>
161
+ </div>
162
+ </div>
163
+ <button class="pill" id="screenshotBtn" title="截图(框选屏幕区域发给 AI)" data-i18n="chat.screenshot">📷 截图</button>
164
+ <button class="pill" id="voiceBtn" title="语音输入(点击开始/停止)" data-i18n="chat.voice">🎤 语音</button>
165
+ <span class="pill" id="skillPill" title="当前智能体" data-i18n="chat.agent_default">🤖 通用助手</span>
166
+ <span class="pill" id="directModePill" style="display:none;" title="电脑操作模式已开启" data-i18n="chat.direct_mode">🖥 电脑操作</span>
167
+ <span id="voiceBadge" class="voice-badge" style="display:none;" data-i18n="chat.listening">● 正在听…</span>
168
+ <span class="spacer"></span>
169
+ <button id="sendBtn" data-i18n="chat.send">▶ 发送</button>
170
+ </div>
171
+ </div>
172
+ <div class="workspace-bar">
173
+ <button class="wb-select" id="workspacePickBtn" title="选择工作区文件夹" data-i18n="modal.new_task_workspace">
174
+ <span class="wb-icon">📂</span>
175
+ <span class="wb-label" id="workspaceCwdBottom" data-i18n="common.loading">加载中…</span>
176
+ <span class="wb-arrow">▾</span>
177
+ </button>
178
+ <div class="wb-perm" id="workspacePermBadge" title="点击配置权限">
179
+ <span>🛡️</span>
180
+ <span id="workspacePermLabel" data-i18n="perm.default">默认权限</span>
181
+ </div>
182
+ </div>
183
+ <div class="call-bar">
184
+ <span class="call-hint" data-i18n="call.hint">通话</span>
185
+ <button id="voiceCallBtn" class="call-btn" data-i18n="call.voice">📞 语音</button>
186
+ <button id="videoCallBtn" class="call-btn" data-i18n="call.video">🎥 视频</button>
187
+ <button id="hangupCallBtn" class="call-btn hangup" style="display:none;" data-i18n="call.hangup">⛔ 挂断</button>
188
+ <span id="callStatus" class="call-status"></span>
189
+ </div>
190
+ </div>
191
+ </div>
192
+
193
+ <!-- 自动化页面 -->
194
+ <div class="page-view" data-view="automations">
195
+ <div class="page-head">
196
+ <div data-i18n="nav.automations"><h2>⚡ 自动化</h2><div class="sub">把常用目标存成指令,一键发起任务</div></div>
197
+ <button id="newAutoBtn" data-i18n="btn.new_automation">+ 新建指令</button>
198
+ </div>
199
+ <div class="section-title">常用快捷指令</div>
200
+ <div class="grid" id="builtinAutoGrid"></div>
201
+ <div class="section-title" style="margin-top:20px;">我的指令</div>
202
+ <div class="grid" id="autoGrid" data-i18n="empty.no_automations"><div class="empty">还没有自定义指令,点击上方「新建指令」或从常用指令保存</div></div>
203
+ </div>
204
+
205
+ <!-- 模板库页面 -->
206
+ <div class="page-view" data-view="templates">
207
+ <div class="page-head">
208
+ <div data-i18n="nav.templates"><h2>📚 模板库</h2><div class="sub">点击模板即可填充到输入框</div></div>
209
+ <button id="newTplBtn" data-i18n="btn.save_template">+ 保存当前为模板</button>
210
+ </div>
211
+ <div class="section-title" data-i18n="tpl.builtin">内置模板</div>
212
+ <div class="grid" id="builtinGrid"></div>
213
+ <div class="section-title" style="margin-top:20px;" id="nodeTplTitle" data-i18n="tpl.node">来自节点</div>
214
+ <div class="grid" id="nodeTplGrid"><div class="empty">暂无节点模板,去「节点管理」添加节点</div></div>
215
+ <div class="section-title" style="margin-top:20px;" id="customTplTitle" data-i18n="tpl.custom">自定义来源</div>
216
+ <div class="grid" id="customTplGrid"><div class="empty">暂无自定义来源模板</div></div>
217
+ <div class="section-title" style="margin-top:20px;" data-i18n="tpl.my">我的模板</div>
218
+ <div class="grid" id="userTplGrid" data-i18n="empty.no_templates"><div class="empty">暂无自定义模板</div></div>
219
+ </div>
220
+
221
+ <!-- 插件市场页面 -->
222
+ <div class="page-view" data-view="market">
223
+ <div class="page-head">
224
+ <div data-i18n="nav.market"><h2>🧩 插件市场</h2><div class="sub">聚合 ClawHub 与 Agent-Foundry 技能生态</div></div>
225
+ <div class="row" style="flex:0 0 auto; gap:8px;">
226
+ <input type="text" id="marketSearch" placeholder="搜索…" style="margin:0;width:160px;" data-i18n="market.search_placeholder" />
227
+ <select id="marketSource" style="margin:0;width:130px;">
228
+ <option value="all" data-i18n="market.source_all">全部来源</option>
229
+ <option value="clawhub">ClawHub</option>
230
+ <option value="agent-foundry">Agent-Foundry</option>
231
+ <option value="node">节点</option>
232
+ <option value="custom">自定义来源</option>
233
+ </select>
234
+ <button id="marketRefresh" data-i18n="btn.refresh">刷新</button>
235
+ </div>
236
+ </div>
237
+ <div class="grid" id="marketGrid" data-i18n="common.loading"><div class="empty">加载中…</div></div>
238
+ <div class="section-title" style="margin-top:20px;" data-i18n="market.installed">已安装</div>
239
+ <div class="grid" id="installedGrid" data-i18n="market.installed"><div class="empty">暂无已安装技能</div></div>
240
+ </div>
241
+
242
+ <!-- 办公助理页面 -->
243
+ <div class="page-view" data-view="office">
244
+ <div class="page-head">
245
+ <div data-i18n="nav.office"><h2>📎 办公助理</h2><div class="sub">文档处理快捷入口,点击即生成提示词</div></div>
246
+ </div>
247
+ <div class="grid" id="officeGrid" data-i18n="common.loading"><div class="empty">加载中…</div></div>
248
+ </div>
249
+
250
+ <!-- 节点管理页面 -->
251
+ <div class="page-view" data-view="nodes">
252
+ <div class="page-head">
253
+ <div><h2>🔗 节点管理</h2><div class="sub">连接外部节点,扩展模板/插件/办公能力来源</div></div>
254
+ <div class="row" style="flex:0 0 auto; gap:8px;">
255
+ <button id="addNodeBtn">+ 添加节点</button>
256
+ <button id="addSourceBtn" class="ghost">+ 自定义来源</button>
257
+ </div>
258
+ </div>
259
+ <div class="section-title">已连接节点</div>
260
+ <div class="grid" id="nodesGrid"><div class="empty">还没有添加节点,点击上方「添加节点」连接外部服务</div></div>
261
+ <div class="section-title" style="margin-top:20px;">自定义来源</div>
262
+ <div class="grid" id="sourcesGrid"><div class="empty">还没有自定义来源,点击上方「自定义来源」添加远程数据源</div></div>
263
+ </div>
264
+
265
+ <!-- 记忆系统页面 -->
266
+ <div class="page-view" data-view="memory">
267
+ <div class="page-head">
268
+ <div data-i18n="nav.memory"><h2>🧠 记忆系统</h2><div class="sub">短期记忆每日自动整理,沉淀长期知识</div></div>
269
+ <div class="row">
270
+ <button id="memRefreshBtn" class="ghost" data-i18n="btn.refresh">🔄 刷新</button>
271
+ <button id="memSummarizeBtn" data-i18n="btn.summarize">✨ 立即总结</button>
272
+ </div>
273
+ </div>
274
+
275
+ <!-- 统计卡片 -->
276
+ <div class="memory-stats" id="memoryStats" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:12px;margin-bottom:20px;">
277
+ <div class="card stat-card">
278
+ <div class="stat-label" data-i18n="mem.stat_short_days">短期记忆天数</div>
279
+ <div class="stat-value" id="statShortDays">-</div>
280
+ </div>
281
+ <div class="card stat-card">
282
+ <div class="stat-label" data-i18n="mem.stat_long_items">长期记忆条目</div>
283
+ <div class="stat-value" id="statLongNotes">-</div>
284
+ </div>
285
+ <div class="card stat-card">
286
+ <div class="stat-label" data-i18n="mem.stat_last_summary">上次总结</div>
287
+ <div class="stat-value stat-date" id="statLastSum">-</div>
288
+ </div>
289
+ <div class="card stat-card">
290
+ <div class="stat-label" data-i18n="mem.stat_next_summary">下次自动总结</div>
291
+ <div class="stat-value stat-date" id="statNextSum">-</div>
292
+ </div>
293
+ </div>
294
+
295
+ <!-- Tab 切换 -->
296
+ <div class="memory-tabs" style="display:flex;gap:8px;margin-bottom:16px;border-bottom:1px solid var(--border);padding-bottom:8px;">
297
+ <button class="mem-tab active" data-memtab="short" style="padding:6px 14px;border-radius:8px;border:1px solid var(--border);background:var(--card);cursor:pointer;font-size:13px;" data-i18n="mem.tab_short">📅 短期记忆</button>
298
+ <button class="mem-tab" data-memtab="long" style="padding:6px 14px;border-radius:8px;border:1px solid var(--border);background:var(--card);cursor:pointer;font-size:13px;" data-i18n="mem.tab_long">💾 长期记忆</button>
299
+ <button class="mem-tab" data-memtab="history" style="padding:6px 14px;border-radius:8px;border:1px solid var(--border);background:var(--card);cursor:pointer;font-size:13px;" data-i18n="mem.tab_history">📜 总结历史</button>
300
+ </div>
301
+
302
+ <!-- 短期记忆面板 -->
303
+ <div class="mem-panel active" id="memShortPanel">
304
+ <div class="row" style="margin-bottom:16px;align-items:center;">
305
+ <input type="date" id="memDateInput" style="margin:0;width:160px;" />
306
+ <button id="memLoadDay" style="margin:0;" data-i18n="btn.view">查看</button>
307
+ <button id="memAddShort" style="margin:0;" class="ghost">+ 添加记录</button>
308
+ <span class="muted" id="memDateLabel" style="margin-left:8px;"></span>
309
+ </div>
310
+ <!-- 添加记录文本框(默认隐藏,点击添加记录后展开) -->
311
+ <div id="memShortEditor" style="display:none;margin-bottom:16px;padding:12px;border:1px solid var(--border);border-radius:8px;background:var(--bg);">
312
+ <textarea id="memShortInput" rows="4" placeholder="直接输入你想记录的内容,点击保存即可添加到今天的短期记忆..." style="width:100%;padding:10px;border:1px solid var(--border);border-radius:6px;background:var(--card);color:var(--ink);font-size:13px;resize:vertical;box-sizing:border-box;"></textarea>
313
+ <div style="margin-top:8px;display:flex;gap:8px;justify-content:flex-end;">
314
+ <button id="memShortCancel" class="ghost">取消</button>
315
+ <button id="memShortSave" class="primary">保存</button>
316
+ </div>
317
+ </div>
318
+ <div class="card memory-content" id="memShortContent">
319
+ <div class="empty" data-i18n="btn.view">选择日期查看短期记忆</div>
320
+ </div>
321
+ </div>
322
+
323
+ <!-- 长期记忆面板 -->
324
+ <div class="mem-panel" id="memLongPanel" style="display:none;">
325
+ <div class="row" style="margin-bottom:16px;align-items:center;">
326
+ <button id="memEditLong" style="margin:0;">✎ 编辑</button>
327
+ <button id="memSaveLong" style="margin:0;display:none;" class="primary">💾 保存</button>
328
+ <button id="memCancelLong" style="margin:0;display:none;" class="ghost">取消</button>
329
+ <button id="memAppendLong" style="margin:0;" class="ghost">+ 追加</button>
330
+ <span class="muted" style="margin-left:8px;">长期记忆会在对话中被 AI 参考</span>
331
+ </div>
332
+ <!-- 追加条目文本框(默认隐藏) -->
333
+ <div id="memLongAppendEditor" style="display:none;margin-bottom:16px;padding:12px;border:1px solid var(--border);border-radius:8px;background:var(--bg);">
334
+ <input type="text" id="memAppendTitle" placeholder="条目标题(如:项目知识/用户偏好)" style="width:100%;padding:8px 10px;border:1px solid var(--border);border-radius:6px;background:var(--card);color:var(--ink);font-size:13px;margin-bottom:8px;box-sizing:border-box;" />
335
+ <textarea id="memAppendContent" rows="3" placeholder="输入你想追加的记忆内容..." style="width:100%;padding:10px;border:1px solid var(--border);border-radius:6px;background:var(--card);color:var(--ink);font-size:13px;resize:vertical;box-sizing:border-box;"></textarea>
336
+ <div style="margin-top:8px;display:flex;gap:8px;justify-content:flex-end;">
337
+ <button id="memAppendCancel" class="ghost">取消</button>
338
+ <button id="memAppendSave" class="primary">追加</button>
339
+ </div>
340
+ </div>
341
+ <div class="card memory-content" id="memLongContent">
342
+ <div class="empty" data-i18n="common.loading">加载中…</div>
343
+ </div>
344
+ <textarea id="memLongEditor" style="display:none;width:100%;min-height:400px;padding:12px;border:1px solid var(--border);border-radius:8px;background:var(--bg);color:var(--ink);font-family:monospace;font-size:13px;resize:vertical;box-sizing:border-box;"></textarea>
345
+ <!-- P1-1: ghost text 补全建议条 -->
346
+ <div id="memGhostBar" style="display:none;margin-top:4px;padding:6px 10px;border:1px dashed var(--border,#ccc);border-radius:6px;background:rgba(45,90,61,0.06);font-family:monospace;font-size:12px;color:var(--muted,#777);white-space:pre-wrap;word-break:break-all;line-height:1.5;">
347
+ <span id="memGhostText" style="color:#888;"></span>
348
+ <span style="margin-left:8px;font-size:10px;color:#aaa;">按 <b>Tab</b> 接受补全 · Esc 取消</span>
349
+ </div>
350
+ </div>
351
+
352
+ <!-- 总结历史面板 -->
353
+ <div class="mem-panel" id="memHistoryPanel" style="display:none;">
354
+ <div class="card memory-content" id="memHistoryContent">
355
+ <div class="empty" data-i18n="empty.no_history">暂无总结记录</div>
356
+ </div>
357
+ </div>
358
+ </div>
359
+
360
+ <!-- 产品发布故事页面 -->
361
+ <div class="page-view" data-view="release">
362
+ <div class="release-container">
363
+ <!-- Hero Section -->
364
+ <div class="release-hero">
365
+ <div class="release-badge">v0.5.1</div>
366
+ <h1 class="release-title">飞虹 Code</h1>
367
+ <p class="release-subtitle">终端 AI 编程智能体 · 自我进化 · 企业级安全</p>
368
+ <p class="release-tagline">三个人,三年,从零到一</p>
369
+ <div class="release-stats">
370
+ <div class="stat-item"><span class="stat-num">M0→M9.1</span><span class="stat-label">全功能里程碑</span></div>
371
+ <div class="stat-item"><span class="stat-num">42+</span><span class="stat-label">单元测试</span></div>
372
+ <div class="stat-item"><span class="stat-num">145</span><span class="stat-label">集成验证断言</span></div>
373
+ <div class="stat-item"><span class="stat-num">MIT</span><span class="stat-label">开源许可证</span></div>
374
+ </div>
375
+ </div>
376
+
377
+ <!-- Timeline Section -->
378
+ <div class="release-timeline">
379
+ <h2 class="section-title">三年历程</h2>
380
+ <div class="timeline">
381
+ <div class="timeline-item">
382
+ <div class="timeline-dot"></div>
383
+ <div class="timeline-content">
384
+ <div class="timeline-date">2023 · 起点</div>
385
+ <h3>三个开发者的初心</h3>
386
+ <p>在泉州一家制造业AI服务公司的办公室里,三个开发者围着一台老旧的台式机,讨论着一个大胆的想法:做一个真正能自主写代码的AI助手。</p>
387
+ <p class="timeline-quote">"为什么AI只能回答问题,而不能动手写代码?"</p>
388
+ <div class="timeline-tags"><span class="tag">M0 脚手架</span><span class="tag">工程初始化</span></div>
389
+ </div>
390
+ </div>
391
+
392
+ <div class="timeline-item">
393
+ <div class="timeline-dot"></div>
394
+ <div class="timeline-content">
395
+ <div class="timeline-date">2024 年 · 探索</div>
396
+ <h3>从 Mock 到真实模型</h3>
397
+ <p>第一年,我们走了很多弯路。最初只能用 Mock 驱动,代码生成完全不可能。接入 DeepSeek、通义千问后,终于看到了希望。</p>
398
+ <p class="timeline-quote">"每一次 API 超时都是一次教训,每一次报错都是成长的机会。"</p>
399
+ <div class="timeline-tags"><span class="tag">M1 模型路由</span><span class="tag">M2 多代理</span></div>
400
+ </div>
401
+ </div>
402
+
403
+ <div class="timeline-item">
404
+ <div class="timeline-dot"></div>
405
+ <div class="timeline-content">
406
+ <div class="timeline-date">2025 · 突破</div>
407
+ <h3>企业级能力与自我进化</h3>
408
+ <p>第二年,客户需求倒逼我们做出企业级功能:RBAC权限、审计链、多租户隔离。同时,我们实现了自我进化——让AI从失败中学习。</p>
409
+ <p class="timeline-quote">"一个不会自我修复的AI,只是一个高级脚本。"</p>
410
+ <div class="timeline-tags"><span class="tag">M3 会话恢复</span><span class="tag">M4 企业级</span><span class="tag">M6 自我进化</span></div>
411
+ </div>
412
+ </div>
413
+
414
+ <div class="timeline-item">
415
+ <div class="timeline-dot active"></div>
416
+ <div class="timeline-content">
417
+ <div class="timeline-date">2026 年 · 发布</div>
418
+ <h3>v0.5.1 正式发布</h3>
419
+ <p>经过上千次测试迭代,飞虹 Code 终于完成 M0→M9.1 全部里程碑。从离线演示到企业部署,从个人开发到团队协用。</p>
420
+ <p class="timeline-quote">"这不仅是代码,是三年心血的结晶。"</p>
421
+ <div class="timeline-tags"><span class="tag">M9 全自动 SWE Agent</span><span class="tag">Web 控制台</span><span class="tag">MIT 开源</span></div>
422
+ </div>
423
+ </div>
424
+ </div>
425
+ </div>
426
+
427
+ <!-- Team Section -->
428
+ <div class="release-team">
429
+ <h2 class="section-title">核心团队</h2>
430
+ <div class="team-grid">
431
+ <div class="team-card">
432
+ <div class="team-avatar">👨‍💻</div>
433
+ <h3>架构师</h3>
434
+ <p>负责整体架构设计,选型 TypeScript + Node.js,搭建工程体系。</p>
435
+ <div class="team-role">首席架构师</div>
436
+ </div>
437
+ <div class="team-card">
438
+ <div class="team-avatar">👩‍💻</div>
439
+ <h3>算法工程师</h3>
440
+ <p>主攻模型路由策略,实现多模型自动选优与降级机制。</p>
441
+ <div class="team-role">AI 算法工程师</div>
442
+ </div>
443
+ <div class="team-card">
444
+ <div class="team-avatar">🧑‍💻</div>
445
+ <h3>后端开发</h3>
446
+ <p>负责企业级安全模块,RBAC、审计链、多租户隔离的核心实现。</p>
447
+ <div class="team-role">后端安全工程师</div>
448
+ </div>
449
+ </div>
450
+ </div>
451
+
452
+ <!-- Challenges Section -->
453
+ <div class="release-challenges">
454
+ <h2 class="section-title">走过的坑</h2>
455
+ <div class="challenges-list">
456
+ <div class="challenge-item">
457
+ <span class="challenge-icon">🔥</span>
458
+ <div>
459
+ <h4>并发控制难题</h4>
460
+ <p>多代理并行时,API 限流导致大量 429 错误。解决方案:引入队列机制 + 指数退避重试。</p>
461
+ </div>
462
+ </div>
463
+ <div class="challenge-item">
464
+ <span class="challenge-icon">🔒</span>
465
+ <div>
466
+ <h4>企业安全合规</h4>
467
+ <p>客户要求审计链不可篡改。解决方案:实现 SHA-256 哈希链,每次写入强制追加。</p>
468
+ </div>
469
+ </div>
470
+ <div class="challenge-item">
471
+ <span class="challenge-icon">🧠</span>
472
+ <div>
473
+ <h4>上下文管理</h4>
474
+ <p>长对话超出 Token 限制。解决方案:实现智能压缩算法,保留关键信息+摘要早期内容。</p>
475
+ </div>
476
+ </div>
477
+ </div>
478
+ </div>
479
+
480
+ <!-- Features Section -->
481
+ <div class="release-features">
482
+ <h2 class="section-title">核心能力</h2>
483
+ <div class="features-grid">
484
+ <div class="feature-card">
485
+ <div class="feature-icon">🔄</div>
486
+ <h4>自我进化</h4>
487
+ <p>记录失败 → 学习经验 → 自动应用</p>
488
+ </div>
489
+ <div class="feature-card">
490
+ <div class="feature-icon">🛡️</div>
491
+ <h4>企业级安全</h4>
492
+ <p>RBAC + 审计链 + 多租户隔离</p>
493
+ </div>
494
+ <div class="feature-card">
495
+ <div class="feature-icon">🌐</div>
496
+ <h4>多模型路由</h4>
497
+ <p>DeepSeek / 通义 / Ollama / OpenAI</p>
498
+ </div>
499
+ <div class="feature-card">
500
+ <div class="feature-icon">⚡</div>
501
+ <h4>离线可用</h4>
502
+ <p>本地 Ollama 支持,数据不出内网</p>
503
+ </div>
504
+ <div class="feature-card">
505
+ <div class="feature-icon">🔧</div>
506
+ <h4>SWE Agent</h4>
507
+ <p>全自动软件工程,读仓→拆解→实现→验证</p>
508
+ </div>
509
+ <div class="feature-card">
510
+ <div class="feature-icon">💬</div>
511
+ <h4>Web 控制台</h4>
512
+ <p>浏览器管理界面,可视化任务与审计</p>
513
+ </div>
514
+ </div>
515
+ </div>
516
+
517
+ <!-- Quote Section -->
518
+ <div class="release-quote">
519
+ <blockquote>"从三个人的小团队,到如今服务百余家制造业企业,飞虹 Code 见证了我们三年的坚持。我们相信,开源是最好的传播方式。"</blockquote>
520
+ <cite>— 吴赐虹,飞扬企源研发中心负责人</cite>
521
+ </div>
522
+
523
+ <!-- CTA Section -->
524
+ <div class="release-cta">
525
+ <h2>开始使用飞虹 Code</h2>
526
+ <div class="cta-buttons">
527
+ <a href="https://github.com/wch887292/feihong-code" target="_blank" class="cta-btn primary">⭐ GitHub Star</a>
528
+ <a href="https://www.npmjs.com/package/feihong-code" target="_blank" class="cta-btn secondary">📦 npm install</a>
529
+ </div>
530
+ <p class="cta-sub">MIT 开源 · 晋江市飞虹智科技企业管理有限公司 · 飞扬企源研发中心</p>
531
+ </div>
532
+ </div>
533
+ </div>
534
+
535
+ <!-- 底部工具栏 -->
536
+ <div class="chat-footbar" id="chatFootbar">
537
+ <div data-i18n="sidebar.chat"><strong>对话任务</strong><span class="muted"> · 提交自然语言需求,云端静默执行并回传结果</span></div>
538
+ <div class="row" style="flex:0 0 auto; gap:8px; align-items:center;">
539
+ <label class="model-label" for="modelSelect" data-i18n="footbar.model">大模型</label>
540
+ <select id="modelSelect" class="model-select" title="切换当前使用的大模型" data-i18n="footbar.model">
541
+ <option value="" data-i18n="footbar.model_default">默认(系统路由)</option>
542
+ </select>
543
+ <button id="modelSettingsShortcut" class="ghost-btn" title="大模型设置" data-i18n="sidebar.settings">🧠</button>
544
+ </div>
545
+ </div>
546
+ <!-- 视频通话窗口 -->
547
+ <div class="video-call-window" id="videoCallWindow" style="display:none;">
548
+ <div class="video-call-header">
549
+ <span>📹 视频通话中</span>
550
+ <div style="display:flex;gap:8px;align-items:center;">
551
+ <button class="video-call-snapshot" id="videoSnapshotBtn" title="截取当前画面发送">📸</button>
552
+ <button class="video-call-close" id="videoCallClose">✕</button>
553
+ </div>
554
+ </div>
555
+ <video id="localVideo" autoplay muted playsinline></video>
556
+ </div>
557
+ </main>
558
+
559
+ <!-- 右侧面板 -->
560
+ <aside class="right-panel" id="rightPanel">
561
+ <div class="right-tabs">
562
+ <div class="right-tab active" data-tab="detail" data-i18n="right.detail">📦 任务详情</div>
563
+ <div class="right-tab" data-tab="preview" data-i18n="right.preview">👁 产物预览</div>
564
+ <div class="right-tab" data-tab="changes" id="changesTab">📝 变更</div>
565
+ <div class="right-tab" data-tab="design" id="designTab">🎨 设计稿</div>
566
+ <div class="right-tab" data-tab="git" id="gitTab">🔀 Git</div>
567
+ <div class="right-tab" data-tab="team" id="teamTab">👥 团队</div>
568
+ <div class="right-tab" data-tab="capabilities" id="capabilitiesTab">🧪 能力中心</div>
569
+ <div class="right-tab" data-tab="computer" id="computerTab" style="display:none;">🖥 电脑操作</div>
570
+ </div>
571
+ <div class="right-body">
572
+ <div class="preview-panel active" id="detailPanel">
573
+ <div id="taskDetail" data-i18n="btn.view"><div class="muted">从顶部选择一个任务查看详情。</div></div>
574
+ </div>
575
+ <div class="preview-panel" id="previewPanel">
576
+ <div class="preview-title" id="previewTitle" data-i18n="right.preview_title">预览</div>
577
+ <div class="preview-content" id="previewContent" data-i18n="right.preview_title"><div class="muted">点击任务或对话中的文件/代码进行预览。</div></div>
578
+ </div>
579
+ <div class="preview-panel" id="computerPanel">
580
+ <div class="computer-controls">
581
+ <button id="screenCaptureBtn" class="pill">📷 截取屏幕</button>
582
+ <span id="mousePos" class="muted" style="font-size:12px;">坐标: -</span>
583
+ </div>
584
+ <div class="screen-preview" id="screenPreview">
585
+ <div class="muted" style="text-align:center;padding:40px;">点击「截取屏幕」查看当前屏幕</div>
586
+ </div>
587
+ <div class="computer-actions">
588
+ <div style="margin-bottom:8px;font-size:13px;font-weight:600;">快捷操作</div>
589
+ <div style="display:flex;gap:6px;flex-wrap:wrap;margin-bottom:10px;">
590
+ <button class="pill" id="clickLeftBtn">左键点击</button>
591
+ <button class="pill" id="clickRightBtn">右键点击</button>
592
+ <button class="pill" id="doubleClickBtn">双击</button>
593
+ </div>
594
+ <div style="margin-bottom:8px;">
595
+ <input type="text" id="typeTextInput" placeholder="输入文字后回车发送" style="width:100%;padding:6px 8px;font-size:12px;border:1px solid var(--border);border-radius:6px;" />
596
+ </div>
597
+ <div style="display:flex;gap:6px;flex-wrap:wrap;">
598
+ <button class="pill" data-key="{ENTER}">回车</button>
599
+ <button class="pill" data-key="{TAB}">Tab</button>
600
+ <button class="pill" data-key="{ESC}">Esc</button>
601
+ <button class="pill" data-key="^c">复制</button>
602
+ <button class="pill" data-key="^v">粘贴</button>
603
+ <button class="pill" data-key="^a">全选</button>
604
+ </div>
605
+ </div>
606
+ </div>
607
+ <!-- P3: 多文件变更面板 -->
608
+ <div class="preview-panel" id="changesPanel">
609
+ <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:10px;">
610
+ <div style="font-size:13px;font-weight:600;">📝 待审批变更 <span id="changesCount" class="badge" style="margin-left:4px;">0</span><span id="changesConflictCount" class="badge" style="margin-left:4px;background:#c0392b;color:#fff;display:none;">0 冲突</span></div>
611
+ <div style="display:flex;gap:6px;">
612
+ <button id="changesDetectBtn" class="ghost-btn" style="font-size:11px;padding:3px 8px;" title="检测文件冲突">⚠️ 检测冲突</button>
613
+ <button id="changesRefreshBtn" class="ghost-btn" style="font-size:11px;padding:3px 8px;">🔄</button>
614
+ <button id="changesCommitBtn" class="ghost-btn" style="font-size:11px;padding:3px 8px;background:#2d5a3d;color:#fff;">✓ 全部提交</button>
615
+ <button id="changesDiscardBtn" class="ghost-btn" style="font-size:11px;padding:3px 8px;">🗑 丢弃</button>
616
+ </div>
617
+ </div>
618
+ <div id="changesList" style="overflow-y:auto;max-height:calc(100vh - 280px);">
619
+ <div class="muted" style="text-align:center;padding:30px;font-size:12px;">暂无暂存变更<br/><span style="font-size:11px;">AI 生成的文件修改会先暂存在这里,审批后才写入磁盘</span></div>
620
+ </div>
621
+ </div>
622
+ <!-- P2-1: 设计稿转代码面板 -->
623
+ <div class="preview-panel" id="designPanel">
624
+ <div style="margin-bottom:10px;font-size:13px;font-weight:600;">🎨 设计稿转代码</div>
625
+ <!-- 图片上传区域 -->
626
+ <div id="designDropZone" style="border:2px dashed var(--border);border-radius:8px;padding:20px;text-align:center;cursor:pointer;margin-bottom:10px;transition:border-color 0.2s;">
627
+ <div style="font-size:24px;margin-bottom:6px;">📷</div>
628
+ <div style="font-size:12px;color:var(--muted);">点击或拖拽上传设计稿图片</div>
629
+ <div style="font-size:10px;color:var(--muted);margin-top:4px;">支持 PNG/JPG/WebP,最大 8MB</div>
630
+ <input type="file" id="designFileInput" accept="image/*" style="display:none;" />
631
+ </div>
632
+ <!-- 图片预览 -->
633
+ <div id="designImagePreview" style="display:none;margin-bottom:10px;">
634
+ <img id="designPreviewImg" style="width:100%;max-height:200px;object-fit:contain;border-radius:6px;border:1px solid var(--border);" />
635
+ <button id="designRemoveImgBtn" style="margin-top:6px;font-size:11px;padding:2px 8px;background:none;border:1px solid var(--border);border-radius:4px;cursor:pointer;color:var(--ink);">🗑 移除图片</button>
636
+ </div>
637
+ <!-- 框架选择 -->
638
+ <div style="margin-bottom:8px;">
639
+ <label style="font-size:12px;font-weight:600;display:block;margin-bottom:4px;">目标框架</label>
640
+ <select id="designFramework" style="width:100%;padding:6px 8px;font-size:12px;border:1px solid var(--border);border-radius:6px;background:var(--card);color:var(--ink);">
641
+ <option value="html">HTML + 内联 CSS</option>
642
+ <option value="tailwind">HTML + Tailwind CSS</option>
643
+ <option value="html-css">HTML + CSS(分离)</option>
644
+ <option value="react">React 组件(JSX)</option>
645
+ <option value="vue">Vue 3 单文件组件</option>
646
+ </select>
647
+ </div>
648
+ <!-- 附加说明 -->
649
+ <div style="margin-bottom:8px;">
650
+ <label style="font-size:12px;font-weight:600;display:block;margin-bottom:4px;">附加说明(可选)</label>
651
+ <textarea id="designInstructions" placeholder="如:使用深色主题、响应式设计、圆角按钮..." style="width:100%;padding:6px 8px;font-size:12px;border:1px solid var(--border);border-radius:6px;resize:vertical;min-height:50px;background:var(--card);color:var(--ink);"></textarea>
652
+ </div>
653
+ <!-- 生成按钮 -->
654
+ <button id="designGenerateBtn" style="width:100%;padding:8px;font-size:13px;font-weight:600;background:#2d5a3d;color:#fff;border:none;border-radius:6px;cursor:pointer;margin-bottom:10px;">✨ 生成代码</button>
655
+ <!-- 生成状态 -->
656
+ <div id="designStatus" style="display:none;font-size:12px;color:var(--muted);text-align:center;margin-bottom:10px;">
657
+ <span style="display:inline-block;width:12px;height:12px;border:2px solid var(--muted);border-top-color:transparent;border-radius:50%;animation:spin 0.8s linear infinite;vertical-align:middle;margin-right:6px;"></span>
658
+ <span id="designStatusText">正在分析设计稿...</span>
659
+ </div>
660
+ <!-- 结果区域:代码 + 预览切换 -->
661
+ <div id="designResult" style="display:none;">
662
+ <div style="display:flex;gap:4px;margin-bottom:8px;">
663
+ <button class="design-result-tab active" data-tab="code" style="flex:1;padding:5px;font-size:11px;border:1px solid var(--border);border-radius:4px;cursor:pointer;background:var(--card);color:var(--ink);">📄 代码</button>
664
+ <button class="design-result-tab" data-tab="preview" style="flex:1;padding:5px;font-size:11px;border:1px solid var(--border);border-radius:4px;cursor:pointer;background:var(--card);color:var(--ink);">👁 预览</button>
665
+ </div>
666
+ <!-- 代码视图 -->
667
+ <div id="designCodeView" style="margin-bottom:10px;">
668
+ <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:4px;">
669
+ <span style="font-size:11px;color:var(--muted);" id="designCodeLang">HTML</span>
670
+ <button id="designCopyBtn" style="font-size:10px;padding:2px 6px;background:none;border:1px solid var(--border);border-radius:3px;cursor:pointer;color:var(--ink);">📋 复制</button>
671
+ </div>
672
+ <pre id="designCode" style="margin:0;max-height:300px;overflow:auto;padding:10px;background:var(--card);border:1px solid var(--border);border-radius:6px;font-size:11px;line-height:1.5;white-space:pre-wrap;word-break:break-all;"></pre>
673
+ </div>
674
+ <!-- 预览视图 -->
675
+ <div id="designPreviewView" style="display:none;margin-bottom:10px;">
676
+ <iframe id="designPreviewFrame" style="width:100%;height:300px;border:1px solid var(--border);border-radius:6px;background:#fff;"></iframe>
677
+ </div>
678
+ <!-- 迭代修正 -->
679
+ <div style="border-top:1px solid var(--border);padding-top:8px;">
680
+ <div style="font-size:12px;font-weight:600;margin-bottom:4px;">🔧 迭代修正</div>
681
+ <textarea id="designFeedback" placeholder="描述需要修改的地方,如:按钮颜色改为蓝色、标题字号增大..." style="width:100%;padding:6px 8px;font-size:12px;border:1px solid var(--border);border-radius:6px;resize:vertical;min-height:40px;margin-bottom:6px;background:var(--card);color:var(--ink);"></textarea>
682
+ <button id="designRefineBtn" style="width:100%;padding:6px;font-size:12px;background:var(--card);color:var(--ink);border:1px solid var(--border);border-radius:6px;cursor:pointer;">🔄 修正代码</button>
683
+ </div>
684
+ </div>
685
+ </div>
686
+ <!-- P2-2: Git 集成面板 -->
687
+ <div class="preview-panel" id="gitPanel">
688
+ <!-- 分支信息和操作 -->
689
+ <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:10px;">
690
+ <div style="font-size:13px;font-weight:600;">🔀 Git <span id="gitBranchName" class="muted" style="font-size:11px;font-weight:normal;"></span></div>
691
+ <div style="display:flex;gap:4px;">
692
+ <button id="gitRefreshBtn" class="ghost-btn" style="font-size:11px;padding:3px 8px;" title="刷新">🔄</button>
693
+ <button id="gitPullBtn" class="ghost-btn" style="font-size:11px;padding:3px 8px;" title="拉取">⬇ 拉取</button>
694
+ <button id="gitPushBtn" class="ghost-btn" style="font-size:11px;padding:3px 8px;" title="推送">⬆ 推送</button>
695
+ </div>
696
+ </div>
697
+ <!-- 非仓库提示 -->
698
+ <div id="gitNoRepo" style="display:none;text-align:center;padding:30px;">
699
+ <div style="font-size:24px;margin-bottom:8px;">📦</div>
700
+ <div class="muted" style="font-size:12px;margin-bottom:10px;">当前目录不是 Git 仓库</div>
701
+ <button id="gitInitBtn" class="ghost-btn" style="font-size:11px;padding:4px 12px;">初始化 Git 仓库</button>
702
+ </div>
703
+ <!-- Git 内容区 -->
704
+ <div id="gitContent" style="display:none;">
705
+ <!-- 分支切换 -->
706
+ <div style="margin-bottom:8px;">
707
+ <select id="gitBranchSelect" style="width:100%;padding:5px 8px;font-size:11px;border:1px solid var(--border);border-radius:4px;background:var(--card);color:var(--ink);"></select>
708
+ </div>
709
+ <!-- 暂存区 -->
710
+ <div style="margin-bottom:10px;">
711
+ <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:4px;">
712
+ <span style="font-size:11px;font-weight:600;color:#2d8a4e;">📥 暂存区 <span id="gitStagedCount" class="muted">0</span></span>
713
+ <button id="gitResetAllBtn" class="ghost-btn" style="font-size:10px;padding:2px 6px;display:none;">全部取消</button>
714
+ </div>
715
+ <div id="gitStagedList" style="max-height:120px;overflow-y:auto;"></div>
716
+ </div>
717
+ <!-- 工作区修改 -->
718
+ <div style="margin-bottom:10px;">
719
+ <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:4px;">
720
+ <span style="font-size:11px;font-weight:600;color:#c0392b;">📝 修改 <span id="gitModifiedCount" class="muted">0</span></span>
721
+ <button id="gitAddAllBtn" class="ghost-btn" style="font-size:10px;padding:2px 6px;display:none;">全部暂存</button>
722
+ </div>
723
+ <div id="gitModifiedList" style="max-height:120px;overflow-y:auto;"></div>
724
+ </div>
725
+ <!-- 未跟踪文件 -->
726
+ <div style="margin-bottom:10px;">
727
+ <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:4px;">
728
+ <span style="font-size:11px;font-weight:600;color:#888;">❓ 未跟踪 <span id="gitUntrackedCount" class="muted">0</span></span>
729
+ </div>
730
+ <div id="gitUntrackedList" style="max-height:80px;overflow-y:auto;"></div>
731
+ </div>
732
+ <!-- 提交 -->
733
+ <div style="border-top:1px solid var(--border);padding-top:8px;">
734
+ <textarea id="gitCommitMessage" placeholder="提交信息(Ctrl+Enter 提交)" style="width:100%;padding:6px 8px;font-size:12px;border:1px solid var(--border);border-radius:6px;resize:vertical;min-height:50px;margin-bottom:6px;background:var(--card);color:var(--ink);"></textarea>
735
+ <button id="gitCommitBtn" style="width:100%;padding:6px;font-size:12px;font-weight:600;background:#2d5a3d;color:#fff;border:none;border-radius:6px;cursor:pointer;">✓ 提交</button>
736
+ </div>
737
+ <!-- 提交历史 -->
738
+ <div style="margin-top:10px;border-top:1px solid var(--border);padding-top:8px;">
739
+ <div style="font-size:11px;font-weight:600;margin-bottom:4px;cursor:pointer;" id="gitLogToggle">📜 提交历史 ▼</div>
740
+ <div id="gitLogList" style="display:none;max-height:150px;overflow-y:auto;font-size:11px;"></div>
741
+ </div>
742
+ </div>
743
+ <!-- Diff 查看模态 -->
744
+ <div id="gitDiffModal" style="display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.5);z-index:1000;display:none;align-items:center;justify-content:center;">
745
+ <div style="background:var(--card);border-radius:8px;padding:16px;max-width:90%;max-height:80%;width:700px;overflow:hidden;display:flex;flex-direction:column;">
746
+ <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;">
747
+ <span id="gitDiffTitle" style="font-size:13px;font-weight:600;">Diff</span>
748
+ <button id="gitDiffCloseBtn" style="background:none;border:none;font-size:18px;cursor:pointer;color:var(--ink);">✕</button>
749
+ </div>
750
+ <pre id="gitDiffContent" style="margin:0;overflow:auto;flex:1;font-size:11px;line-height:1.5;white-space:pre-wrap;word-break:break-all;"></pre>
751
+ </div>
752
+ </div>
753
+ </div>
754
+ <!-- P2-3: 团队协作面板 -->
755
+ <div class="preview-panel" id="teamPanel">
756
+ <!-- 团队信息和统计 -->
757
+ <div style="margin-bottom:10px;">
758
+ <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:8px;">
759
+ <span style="font-size:13px;font-weight:600;">👥 <span id="teamName">团队</span></span>
760
+ <button id="teamRefreshBtn" class="ghost-btn" style="font-size:11px;padding:3px 8px;">🔄</button>
761
+ </div>
762
+ <div style="display:grid;grid-template-columns:1fr 1fr;gap:6px;margin-bottom:10px;">
763
+ <div style="background:var(--card);padding:8px;border-radius:6px;text-align:center;">
764
+ <div style="font-size:16px;font-weight:600;color:#2d5a3d;" id="teamMemberCount">0</div>
765
+ <div style="font-size:10px;color:var(--muted);">成员</div>
766
+ </div>
767
+ <div style="background:var(--card);padding:8px;border-radius:6px;text-align:center;">
768
+ <div style="font-size:16px;font-weight:600;color:#2d5a3d;" id="teamTaskCount">0</div>
769
+ <div style="font-size:10px;color:var(--muted);">任务</div>
770
+ </div>
771
+ </div>
772
+ <!-- P7-4: 多 agent 协作总览(状态漏斗 + 成员负载) -->
773
+ <div id="teamOverview" style="display:none;margin-bottom:10px;"></div>
774
+ </div>
775
+ <!-- Tab 切换 -->
776
+ <div style="display:flex;gap:4px;margin-bottom:8px;border-bottom:1px solid var(--border);padding-bottom:6px;">
777
+ <button class="team-tab active" data-tab="members" style="flex:1;padding:5px;font-size:11px;border:none;background:none;cursor:pointer;color:var(--ink);border-bottom:2px solid #2d5a3d;font-weight:600;">👤 成员</button>
778
+ <button class="team-tab" data-tab="tasks" style="flex:1;padding:5px;font-size:11px;border:none;background:none;cursor:pointer;color:var(--muted);border-bottom:2px solid transparent;">📋 任务</button>
779
+ </div>
780
+ <!-- 成员管理 -->
781
+ <div id="teamMembersTab">
782
+ <div style="display:flex;gap:4px;margin-bottom:8px;">
783
+ <input type="text" id="teamInviteName" placeholder="姓名" style="flex:1;padding:5px 8px;font-size:11px;border:1px solid var(--border);border-radius:4px;background:var(--card);color:var(--ink);" />
784
+ <input type="email" id="teamInviteEmail" placeholder="邮箱" style="flex:1;padding:5px 8px;font-size:11px;border:1px solid var(--border);border-radius:4px;background:var(--card);color:var(--ink);" />
785
+ <button id="teamInviteBtn" style="padding:5px 10px;font-size:11px;background:#2d5a3d;color:#fff;border:none;border-radius:4px;cursor:pointer;">邀请</button>
786
+ </div>
787
+ <div id="teamMembersList" style="max-height:300px;overflow-y:auto;"></div>
788
+ </div>
789
+ <!-- 任务管理 -->
790
+ <div id="teamTasksTab" style="display:none;">
791
+ <div style="display:flex;gap:4px;margin-bottom:8px;">
792
+ <input type="text" id="teamTaskTitle" placeholder="任务标题" style="flex:1;padding:5px 8px;font-size:11px;border:1px solid var(--border);border-radius:4px;background:var(--card);color:var(--ink);" />
793
+ <button id="teamCreateTaskBtn" style="padding:5px 10px;font-size:11px;background:#2d5a3d;color:#fff;border:none;border-radius:4px;cursor:pointer;">创建</button>
794
+ </div>
795
+ <div style="display:flex;gap:4px;margin-bottom:8px;flex-wrap:wrap;">
796
+ <button class="team-task-filter active" data-status="" style="padding:3px 8px;font-size:10px;border:1px solid var(--border);border-radius:3px;cursor:pointer;background:var(--card);color:var(--ink);">全部</button>
797
+ <button class="team-task-filter" data-status="todo" style="padding:3px 8px;font-size:10px;border:1px solid var(--border);border-radius:3px;cursor:pointer;background:var(--card);color:var(--ink);">待办</button>
798
+ <button class="team-task-filter" data-status="in-progress" style="padding:3px 8px;font-size:10px;border:1px solid var(--border);border-radius:3px;cursor:pointer;background:var(--card);color:var(--ink);">进行中</button>
799
+ <button class="team-task-filter" data-status="review" style="padding:3px 8px;font-size:10px;border:1px solid var(--border);border-radius:3px;cursor:pointer;background:var(--card);color:var(--ink);">评审</button>
800
+ <button class="team-task-filter" data-status="done" style="padding:3px 8px;font-size:10px;border:1px solid var(--border);border-radius:3px;cursor:pointer;background:var(--card);color:var(--ink);">完成</button>
801
+ </div>
802
+ <div id="teamTasksList" style="max-height:300px;overflow-y:auto;"></div>
803
+ </div>
804
+ </div>
805
+ <!-- P0-3: 能力中心面板(v7.2 新能力前端接线:语音/资料库/插件市场) -->
806
+ <div class="preview-panel" id="capabilitiesPanel">
807
+ <div style="margin-bottom:10px;">
808
+ <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:8px;">
809
+ <span style="font-size:13px;font-weight:600;">🧪 能力中心 <span style="font-size:10px;color:var(--muted);">v7.2 实测可用</span></span>
810
+ </div>
811
+ <!-- 语音编程 -->
812
+ <div style="background:var(--card);padding:8px;border-radius:6px;margin-bottom:8px;">
813
+ <div style="font-size:11px;font-weight:600;margin-bottom:6px;">🎙 语音指令解析</div>
814
+ <div style="display:flex;gap:6px;">
815
+ <input id="capVoiceInput" placeholder="如:打开文件 / 生成排序函数" style="flex:1;font-size:11px;padding:4px 6px;" />
816
+ <button id="capVoiceBtn" class="primary" style="font-size:11px;padding:4px 10px;">解析</button>
817
+ </div>
818
+ <div id="capVoiceResult" style="font-size:11px;margin-top:6px;color:var(--muted);"></div>
819
+ </div>
820
+ <!-- AI 资料库 -->
821
+ <div style="background:var(--card);padding:8px;border-radius:6px;margin-bottom:8px;">
822
+ <div style="font-size:11px;font-weight:600;margin-bottom:6px;">📚 AI 资料库</div>
823
+ <div style="display:flex;gap:6px;">
824
+ <input id="capKnowledgeQuery" placeholder="搜索资料(如:私有化部署)" style="flex:1;font-size:11px;padding:4px 6px;" />
825
+ <button id="capKnowledgeSearchBtn" class="primary" style="font-size:11px;padding:4px 10px;">搜索</button>
826
+ </div>
827
+ <div id="capKnowledgeResult" style="font-size:11px;margin-top:6px;max-height:140px;overflow-y:auto;color:var(--muted);"></div>
828
+ </div>
829
+ <!-- 插件市场 -->
830
+ <div style="background:var(--card);padding:8px;border-radius:6px;">
831
+ <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:6px;">
832
+ <span style="font-size:11px;font-weight:600;">🧩 插件市场</span>
833
+ <button id="capPluginsBtn" class="ghost-btn" style="font-size:11px;padding:2px 8px;">🔄 加载</button>
834
+ </div>
835
+ <div id="capPluginsResult" style="font-size:11px;max-height:140px;overflow-y:auto;color:var(--muted);"></div>
836
+ </div>
837
+ </div>
838
+ </div>
839
+ </div>
840
+ </aside>
841
+ </div>
842
+ </div>
843
+
844
+ <!-- 模态框区域 -->
845
+ <div class="mask" id="autoModal">
846
+ <div class="modal">
847
+ <span class="close-x" data-close="autoModal">✕</span>
848
+ <h3 data-i18n="modal.auto_title">新建快捷指令</h3>
849
+ <p class="hint" data-i18n="sidebar.automations">保存后可在「自动化」页一键发起任务。</p>
850
+ <label for="autoName" data-i18n="modal.auto_name">指令名称</label>
851
+ <input type="text" id="autoName" placeholder="如:每日构建检查" data-i18n="modal.auto_name_ph" />
852
+ <label for="autoGoal" data-i18n="modal.auto_goal">目标(提交给模型的需求)</label>
853
+ <textarea id="autoGoal" placeholder="运行 npm test 并汇总失败用例…" data-i18n="modal.auto_goal_ph"></textarea>
854
+ <div class="footer">
855
+ <button class="ghost" data-close="autoModal" data-i18n="btn.cancel">取消</button>
856
+ <button id="autoSaveBtn" data-i18n="btn.save">保存</button>
857
+ </div>
858
+ </div>
859
+ </div>
860
+
861
+ <!-- 添加节点模态框 -->
862
+ <div class="mask" id="nodeModal">
863
+ <div class="modal">
864
+ <span class="close-x" data-close="nodeModal">✕</span>
865
+ <h3 id="nodeModalTitle">添加节点</h3>
866
+ <p class="hint">连接外部节点,扩展模板/插件/办公能力来源。节点需提供标准 API 或本地 JSON 文件。</p>
867
+ <input type="hidden" id="nodeEditId" />
868
+ <label for="nodeName">节点名称</label>
869
+ <input type="text" id="nodeName" placeholder="如:公司内部技能库" />
870
+ <label for="nodeType">节点类型</label>
871
+ <select id="nodeType">
872
+ <option value="http">HTTP API 节点</option>
873
+ <option value="local">本地目录节点</option>
874
+ <option value="git">Git 仓库节点</option>
875
+ </select>
876
+ <label for="nodeUrl">地址(URL 或本地路径)</label>
877
+ <input type="text" id="nodeUrl" placeholder="如:https://api.example.com 或 D:\nodes\my-node" />
878
+ <label for="nodeApiKey">API Key(可选)</label>
879
+ <input type="password" id="nodeApiKey" placeholder="留空表示不需要认证" autocomplete="off" />
880
+ <label>提供的能力</label>
881
+ <div style="display:flex;gap:16px;margin-bottom:12px;">
882
+ <label style="display:flex;align-items:center;gap:6px;cursor:pointer;"><input type="checkbox" id="nodeCapTemplates" checked /> 模板</label>
883
+ <label style="display:flex;align-items:center;gap:6px;cursor:pointer;"><input type="checkbox" id="nodeCapSkills" checked /> 插件</label>
884
+ <label style="display:flex;align-items:center;gap:6px;cursor:pointer;"><input type="checkbox" id="nodeCapOffice" checked /> 办公</label>
885
+ </div>
886
+ <div class="footer">
887
+ <button class="ghost" data-close="nodeModal">取消</button>
888
+ <button id="nodeSaveBtn" class="primary">保存并测试连接</button>
889
+ </div>
890
+ </div>
891
+ </div>
892
+
893
+ <!-- 添加自定义来源模态框 -->
894
+ <div class="mask" id="sourceModal">
895
+ <div class="modal">
896
+ <span class="close-x" data-close="sourceModal">✕</span>
897
+ <h3 id="sourceModalTitle">添加自定义来源</h3>
898
+ <p class="hint">添加远程 JSON 数据源,自动拉取模板/插件/办公能力。</p>
899
+ <input type="hidden" id="sourceEditId" />
900
+ <label for="sourceName">来源名称</label>
901
+ <input type="text" id="sourceName" placeholder="如:团队共享模板" />
902
+ <label for="sourceType">来源类型</label>
903
+ <select id="sourceType">
904
+ <option value="templates">模板</option>
905
+ <option value="skills">插件</option>
906
+ <option value="office">办公能力</option>
907
+ </select>
908
+ <label for="sourceUrl">JSON 数据地址</label>
909
+ <input type="text" id="sourceUrl" placeholder="https://example.com/templates.json" />
910
+ <div class="footer">
911
+ <button class="ghost" data-close="sourceModal">取消</button>
912
+ <button id="sourceSaveBtn" class="primary">保存</button>
913
+ </div>
914
+ </div>
915
+ </div>
916
+
917
+ <div class="mask" id="tplModal">
918
+ <div class="modal">
919
+ <span class="close-x" data-close="tplModal">✕</span>
920
+ <h3 data-i18n="btn.save">保存为模板</h3>
921
+ <label for="tplTitle" data-i18n="modal.tpl_title_label">模板标题</label>
922
+ <input type="text" id="tplTitle" placeholder="如:SQL 优化" data-i18n="modal.tpl_title_ph" />
923
+ <label for="tplCategory" data-i18n="modal.tpl_category">分类</label>
924
+ <input type="text" id="tplCategory" placeholder="自定义" data-i18n="modal.tpl_category_ph" />
925
+ <label for="tplGoal" data-i18n="modal.tpl_goal">目标内容</label>
926
+ <textarea id="tplGoal" placeholder="粘贴要保存的需求文本…" data-i18n="btn.save"></textarea>
927
+ <div class="footer">
928
+ <button class="ghost" data-close="tplModal" data-i18n="btn.cancel">取消</button>
929
+ <button id="tplSaveBtn" data-i18n="btn.save">保存</button>
930
+ </div>
931
+ </div>
932
+ </div>
933
+
934
+ <div class="mask" id="permModal">
935
+ <div class="modal" style="width:480px;">
936
+ <span class="close-x" data-close="permModal">✕</span>
937
+ <h3 data-i18n="modal.perm_title">🔒 权限处理窗口</h3>
938
+ <p class="hint" data-i18n="modal.perm_hint">配置工作期间 AI 可读范围及可操作权限。</p>
939
+ <div class="perm-section">
940
+ <div class="perm-title" data-i18n="modal.perm_read_scope">可读范围</div>
941
+ <div class="perm-row">
942
+ <input type="radio" name="readScope" id="scopeWorkspace" value="workspace" checked />
943
+ <label for="scopeWorkspace" data-i18n="modal.perm_workspace">仅当前工作区</label>
944
+ </div>
945
+ <div class="perm-row">
946
+ <input type="radio" name="readScope" id="scopeSpecified" value="specified" />
947
+ <label for="scopeSpecified" data-i18n="modal.perm_specified">指定目录</label>
948
+ </div>
949
+ <div class="perm-row">
950
+ <input type="text" id="permReadPath" placeholder="输入允许的目录路径" style="margin:0;" data-i18n="modal.perm_path_ph" />
951
+ </div>
952
+ <div class="perm-row">
953
+ <input type="radio" name="readScope" id="scopeAll" value="all" />
954
+ <label for="scopeAll" data-i18n="modal.perm_all">全部文件</label>
955
+ </div>
956
+ </div>
957
+ <div class="perm-section">
958
+ <div class="perm-title" data-i18n="modal.perm_actions">操作权限</div>
959
+ <div class="perm-row">
960
+ <input type="checkbox" id="permRead" checked />
961
+ <label for="permRead" data-i18n="modal.perm_read">读取文件</label>
962
+ </div>
963
+ <div class="perm-row">
964
+ <input type="checkbox" id="permWrite" />
965
+ <label for="permWrite" data-i18n="modal.perm_write">写入文件</label>
966
+ </div>
967
+ <div class="perm-row">
968
+ <input type="checkbox" id="permShell" />
969
+ <label for="permShell" data-i18n="modal.perm_shell">执行命令</label>
970
+ </div>
971
+ <div class="perm-row">
972
+ <input type="checkbox" id="permNetwork" checked />
973
+ <label for="permNetwork" data-i18n="modal.perm_network">访问网络</label>
974
+ </div>
975
+ <div class="perm-row">
976
+ <input type="checkbox" id="permBrowser" />
977
+ <label for="permBrowser" data-i18n="modal.perm_browser">浏览器控制</label>
978
+ </div>
979
+ </div>
980
+ <div class="footer">
981
+ <button class="ghost" data-close="permModal" data-i18n="btn.cancel">取消</button>
982
+ <button id="permSaveBtn" data-i18n="btn.save">保存</button>
983
+ </div>
984
+ </div>
985
+ </div>
986
+
987
+ <div class="mask" id="agentModal">
988
+ <div class="modal" style="width:420px;">
989
+ <span class="close-x" data-close="agentModal">✕</span>
990
+ <h3 data-i18n="chat.agent_type">🤖 选择智能体类型</h3>
991
+ <p class="hint" data-i18n="modal.agent_hint">不同智能体会自动调整提示词与执行策略。</p>
992
+ <div class="agent-grid" id="agentGrid"></div>
993
+ <div class="footer">
994
+ <button class="ghost" data-close="agentModal" data-i18n="btn.cancel">取消</button>
995
+ </div>
996
+ </div>
997
+ </div>
998
+
999
+ <div class="crop-overlay" id="cropOverlay" style="display:none;">
1000
+ <div class="crop-tip" id="cropTip" data-i18n="crop.tip">按住鼠标拖拽选择截图区域 · 松开确认 · ESC 取消</div>
1001
+ <div class="crop-selection" id="cropSelection"></div>
1002
+ <video id="cropVideo" style="display:none;"></video>
1003
+ </div>
1004
+
1005
+ <div class="mask" id="folderPickerModal">
1006
+ <div class="modal" style="width:560px;">
1007
+ <span class="close-x" data-close="folderPickerModal">✕</span>
1008
+ <h3 id="fpTitle">📂 选择工作区文件夹</h3>
1009
+
1010
+ <!-- 驱动器选择视图 -->
1011
+ <div id="fpDrivesView">
1012
+ <p class="hint" style="margin:8px 0;">请选择一个驱动器,然后在其中选择或新建文件夹作为工作区。</p>
1013
+ <div class="fp-drives-grid" id="fpDrivesGrid" style="display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin:10px 0;max-height:320px;overflow:auto;"></div>
1014
+ </div>
1015
+
1016
+ <!-- 文件夹选择视图 -->
1017
+ <div id="fpFoldersView" style="display:none;">
1018
+ <div style="display:flex;align-items:center;gap:8px;margin-bottom:8px;">
1019
+ <button class="ghost sm" id="fpBackToDrives" style="flex-shrink:0;">← 驱动器</button>
1020
+ <button class="ghost sm" id="fpUpDir" style="flex-shrink:0;">↑ 上级</button>
1021
+ <div class="fp-path" id="fpPath" style="flex:1;font-size:12px;color:var(--ink-2);word-break:break-all;padding:6px 8px;background:var(--bg);border-radius:6px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">—</div>
1022
+ </div>
1023
+ <div style="display:flex;gap:8px;margin-bottom:8px;">
1024
+ <button class="ghost sm" id="fpNewFolder">+ 新建文件夹</button>
1025
+ <button class="ghost sm" id="fpRenameFolder" disabled>✎ 重命名</button>
1026
+ </div>
1027
+ <div class="file-tree" id="fpTree" style="max-height:260px;overflow:auto;margin:10px 0;"></div>
1028
+ </div>
1029
+
1030
+ <!-- 新建文件夹输入框 -->
1031
+ <div id="fpMkdirBar" style="display:none;gap:8px;margin-bottom:8px;">
1032
+ <input type="text" id="fpMkdirName" placeholder="输入新文件夹名称" style="flex:1;padding:6px 10px;border:1px solid var(--line);border-radius:6px;font-size:13px;" />
1033
+ <button class="primary sm" id="fpMkdirConfirm">确定</button>
1034
+ <button class="ghost sm" id="fpMkdirCancel">取消</button>
1035
+ </div>
1036
+
1037
+ <!-- 重命名输入框 -->
1038
+ <div id="fpRenameBar" style="display:none;gap:8px;margin-bottom:8px;">
1039
+ <input type="text" id="fpRenameName" placeholder="输入新名称" style="flex:1;padding:6px 10px;border:1px solid var(--line);border-radius:6px;font-size:13px;" />
1040
+ <button class="primary sm" id="fpRenameConfirm">确定</button>
1041
+ <button class="ghost sm" id="fpRenameCancel">取消</button>
1042
+ </div>
1043
+
1044
+ <div class="footer">
1045
+ <button class="ghost" id="fpCancel" data-close="folderPickerModal">取消</button>
1046
+ <button class="primary" id="fpConfirm" disabled>选择此文件夹</button>
1047
+ </div>
1048
+ </div>
1049
+ </div>
1050
+
1051
+ <div class="mask" id="modelModal">
1052
+ <div class="modal" style="width:520px;">
1053
+ <span class="close-x" data-close="modelModal">✕</span>
1054
+ <h3 data-i18n="sidebar.settings">🧠 大模型设置</h3>
1055
+ <p class="hint" data-i18n="footbar.model">配置自定义大模型,可保存多个并在对话中随时切换。勾选「默认」的项将作为对话默认模型。</p>
1056
+ <div class="model-list" id="modelList"></div>
1057
+ <div class="model-form">
1058
+ <div class="form-row">
1059
+ <div class="form-field">
1060
+ <label data-i18n="modal.model_name">模型名称 *</label>
1061
+ <input type="text" id="modelName" placeholder="如 GPT-4o / 通义千问 / 自建模型" data-i18n="modal.model_name_ph" />
1062
+ </div>
1063
+ <div class="form-field">
1064
+ <label data-i18n="modal.model_api">API 地址</label>
1065
+ <input type="text" id="modelApiBase" placeholder="https://api.openai.com/v1" data-i18n="modal.model_api_ph" />
1066
+ </div>
1067
+ </div>
1068
+ <div class="form-field">
1069
+ <label data-i18n="modal.model_key">密钥(API Key)</label>
1070
+ <input type="password" id="modelApiKey" placeholder="sk-..." autocomplete="off" data-i18n="modal.model_key_ph" />
1071
+ </div>
1072
+ <div class="form-field">
1073
+ <label data-i18n="modal.model_reasoning">推理过程运行内容(中间环节)</label>
1074
+ <textarea id="modelReasoning" rows="3" placeholder="配置该模型在中间推理环节的运行内容,例如:先列出需求拆解,再给出实现方案,最后输出代码。" data-i18n="modal.model_reasoning_ph"></textarea>
1075
+ </div>
1076
+ <div class="form-actions">
1077
+ <button id="modelSaveBtn" class="primary" data-i18n="btn.save">保存配置</button>
1078
+ <button id="modelResetBtn" class="ghost" data-i18n="btn.clear_form">清空表单</button>
1079
+ <span id="modelFormMsg" class="model-form-msg"></span>
1080
+ </div>
1081
+ </div>
1082
+ <div class="footer">
1083
+ <button class="ghost" data-close="modelModal" data-i18n="btn.close">关闭</button>
1084
+ </div>
1085
+ </div>
1086
+ </div>
1087
+
1088
+ <div class="mask" id="newTaskModal">
1089
+ <div class="modal" style="width:560px;">
1090
+ <span class="close-x" data-close="newTaskModal">✕</span>
1091
+ <h3 data-i18n="sidebar.chat">+ 新建对话任务</h3>
1092
+ <p class="hint" data-i18n="modal.new_task_hint">创建一个全新任务,中部对话栏的所有消息都将归属该任务运行(支持多轮连续对话)。</p>
1093
+ <div class="nt-form">
1094
+ <label class="nt-label" data-i18n="modal.new_task_label">任务描述 <span style="color:var(--err)">*</span></label>
1095
+ <textarea id="ntGoal" rows="5" placeholder="例如:请读取当前工作区 package.json,告诉我其中的 name 与 version 字段" data-i18n="modal.new_task_workspace"></textarea>
1096
+ <div class="nt-row">
1097
+ <div>
1098
+ <label class="nt-label" data-i18n="modal.new_task_agent">智能体类型</label>
1099
+ <select id="ntAgentType"></select>
1100
+ </div>
1101
+ <div>
1102
+ <label class="nt-label" data-i18n="modal.new_task_workspace">工作区</label>
1103
+ <select id="ntWorkspaceDir"></select>
1104
+ </div>
1105
+ </div>
1106
+ <div class="nt-hint" data-i18n="modal.new_task_workspace">工作区默认使用底部当前所选目录;若选择「默认」,则沿用服务器工作区。</div>
1107
+ </div>
1108
+ <div class="footer">
1109
+ <button class="ghost" data-close="newTaskModal" data-i18n="btn.cancel">取消</button>
1110
+ <button class="primary" id="ntCreateBtn" data-i18n="btn.create_task">创建任务</button>
1111
+ </div>
1112
+ </div>
1113
+ </div>
1114
+
1115
+ <div class="mask" id="settingsModal">
1116
+ <div class="modal" style="width:560px;">
1117
+ <span class="close-x" data-close="settingsModal">✕</span>
1118
+ <h3 data-i18n="sidebar.settings">⚙️ 设置</h3>
1119
+ <div class="settings-layout">
1120
+ <div class="settings-nav">
1121
+ <div class="settings-cat active" data-cat="general" data-i18n="settings.general">通用</div>
1122
+ <div class="settings-cat" data-cat="internal" data-i18n="settings.layout">栏目配置</div>
1123
+ </div>
1124
+ <div class="settings-body" id="settingsBody">
1125
+ <div class="settings-group" data-group="general">
1126
+ <div class="settings-item" data-action="perm">
1127
+ <span class="si-icon">🔒</span>
1128
+ <div class="si-main" data-i18n="modal.perm_read_scope"><div class="si-title">权限处理</div><div class="si-desc">配置工作期间可读范围与操作权限</div></div>
1129
+ <span class="si-arrow">›</span>
1130
+ </div>
1131
+ <div class="settings-item" data-action="theme">
1132
+ <span class="si-icon">🎨</span>
1133
+ <div class="si-main" data-i18n="settings.theme"><div class="si-title">外观</div><div class="si-desc">切换浅色 / 深色主题</div></div>
1134
+ <span class="si-arrow">›</span>
1135
+ </div>
1136
+ <hr style="border:none;border-top:1px solid var(--line);margin:8px 0;">
1137
+ <div style="padding:8px 0;">
1138
+ <div style="font-weight:600;font-size:13px;color:var(--ink);margin-bottom:8px;" data-i18n="settings.session">💬 会话管理</div>
1139
+ <div style="display:flex;flex-direction:column;gap:8px;">
1140
+ <label style="display:flex;align-items:center;gap:8px;font-size:13px;cursor:pointer;">
1141
+ <input type="checkbox" class="session-toggle" data-key="autoResetOnNew">
1142
+ <span data-i18n="settings.session_auto_new">发送消息前自动新建对话</span>
1143
+ </label>
1144
+ <label style="display:flex;align-items:center;gap:8px;font-size:13px;cursor:pointer;">
1145
+ <input type="checkbox" class="session-toggle" data-key="autoResetOnOpen">
1146
+ <span data-i18n="settings.session_auto_open">页面打开时自动新建对话</span>
1147
+ </label>
1148
+ <label style="display:flex;align-items:center;gap:8px;font-size:13px;cursor:pointer;">
1149
+ <input type="checkbox" class="session-toggle" data-key="clearHistoryOnNew">
1150
+ <span data-i18n="settings.session_clear">新建对话时清空历史上下文</span>
1151
+ </label>
1152
+ </div>
1153
+ </div>
1154
+ </div>
1155
+ <div class="settings-group" data-group="internal" style="display:none;">
1156
+ <div class="settings-item" data-action="model-custom" id="modelCustomItem">
1157
+ <span class="si-icon">🧠</span>
1158
+ <div class="si-main">
1159
+ <div class="si-title" data-i18n="sidebar.settings">大模型自定义设置</div>
1160
+ <div class="si-desc" data-i18n="footbar.model">自由添加并配置自定义大模型,提供大模型选择列表,可设为默认</div>
1161
+ </div>
1162
+ <span class="si-arrow">›</span>
1163
+ </div>
1164
+ <div class="model-manage" id="modelManage" style="display:none;">
1165
+ <div class="mm-list" id="modelListInline"></div>
1166
+ <div class="mm-divider"><span>添加新模型</span></div>
1167
+ <div class="mm-form">
1168
+ <div class="mm-form-title">填写模型信息</div>
1169
+ <input type="text" id="imName" placeholder="模型名称(必填)" data-i18n="modal.model_name" />
1170
+ <input type="text" id="imBase" placeholder="API 地址(如 https://api.openai.com/v1)" data-i18n="modal.model_api" />
1171
+ <input type="password" id="imKey" placeholder="API Key(编辑时留空保留原值)" autocomplete="off" />
1172
+ <textarea id="imReasoning" rows="2" placeholder="推理中间环节内容(可选)"></textarea>
1173
+ <div class="mm-form-actions">
1174
+ <button id="imSave" class="primary sm" data-i18n="btn.save">保存</button>
1175
+ <button id="imReset" class="ghost sm">清空</button>
1176
+ <span id="imMsg" class="mm-form-msg"></span>
1177
+ </div>
1178
+ </div>
1179
+ </div>
1180
+ </div>
1181
+ </div>
1182
+ </div>
1183
+ <div class="footer">
1184
+ <button class="ghost" data-close="settingsModal" data-i18n="btn.close">关闭</button>
1185
+ </div>
1186
+ </div>
1187
+ </div>
1188
+
1189
+ <div class="bottom-sheet-mask" id="userMenuMask">
1190
+ <div class="bottom-sheet" id="userMenu">
1191
+ <div class="sheet-header">
1192
+ <div class="topbar-avatar" style="width:40px;height:40px;border-radius:50%;background:var(--brand-soft);display:flex;align-items:center;justify-content:center;font-size:20px;">🦐</div>
1193
+ <div>
1194
+ <div class="topbar-phone" id="sheetPhone">未登录</div>
1195
+ <div class="muted">免费版</div>
1196
+ </div>
1197
+ </div>
1198
+ <div class="sheet-item" data-action="version" data-i18n="menu.version"><span class="icon">🎖</span>体验版<span class="right">当前</span></div>
1199
+ <div class="sheet-item" data-action="buddy" data-i18n="menu.buddy"><span class="icon">⛽</span>Buddy 加油站</div>
1200
+ <div class="sheet-item" data-action="invite" data-i18n="menu.invite"><span class="icon">👥</span>去邀约<span class="right">最高得会员</span></div>
1201
+ <div class="sheet-item" data-action="points" data-i18n="menu.points"><span class="icon">💎</span>积分余额</div>
1202
+ <div class="sheet-item" data-action="growth" data-i18n="menu.growth"><span class="icon">🌱</span>成长计划<span class="right">连登有奖</span></div>
1203
+ <div class="sheet-item" data-action="settings" data-i18n="sidebar.settings"><span class="icon">⚙️</span>设置</div>
1204
+ <div class="sheet-item" data-action="theme" data-i18n="settings.theme"><span class="icon">🎨</span>外观</div>
1205
+ <div class="sheet-item" data-action="help" data-i18n="menu.help"><span class="icon">❓</span>帮助与反馈</div>
1206
+ <div class="sheet-item" data-action="update" data-i18n="menu.update"><span class="icon">🔄</span>检查更新</div>
1207
+ <div class="sheet-item" data-action="logout" data-i18n="menu.logout"><span class="icon">↩️</span>退出登录</div>
1208
+ </div>
1209
+ </div>
1210
+
1211
+ <div class="mask" id="welcomeGuideModal">
1212
+ <div class="modal">
1213
+ <span class="close-x" data-close="welcomeGuideModal">✕</span>
1214
+ <div class="welcome-guide-header">
1215
+ <div class="icon">🎉</div>
1216
+ <div>
1217
+ <h3>欢迎使用飞虹 Code!</h3>
1218
+ <p>系统已为您准备了三个引导任务,帮助您快速上手</p>
1219
+ </div>
1220
+ </div>
1221
+ <div class="welcome-task-list" id="welcomeTaskList">
1222
+ <!-- 动态填充 -->
1223
+ </div>
1224
+ <div class="footer">
1225
+ <button class="ghost" data-close="welcomeGuideModal">稍后再说</button>
1226
+ <button class="primary" id="welcomeRunAllBtn">▶ 全部运行</button>
1227
+ </div>
1228
+ </div>
1229
+ </div>
1230
+
1231
+ <input type="file" id="fileInput" />
1232
+ <input type="file" id="imageInput" accept="image/*" />
1233
+ <div class="toast" id="toast"></div>
1234
+
1235
+ <script src="js/mock-api.js"></script>
1236
+ <script src="js/utils.js"></script>
1237
+ <script src="js/monaco-editor.js"></script>
1238
+ <script src="js/api.js"></script>
1239
+ <script src="js/ui.js"></script>
1240
+ <script src="js/app.js"></script>
1241
+ </body>
1242
+ </html>