codebee 0.1.95 → 0.1.97

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 (144) hide show
  1. package/CHANGELOG.md +733 -720
  2. package/LICENSE +21 -21
  3. package/README.md +516 -509
  4. package/app/core/acceptance.py +100 -100
  5. package/app/core/agent_context.py +118 -0
  6. package/app/core/aiflavor.py +197 -197
  7. package/app/core/analytics.py +38 -38
  8. package/app/core/artifacts.py +148 -148
  9. package/app/core/assets.py +110 -110
  10. package/app/core/attachments.py +623 -623
  11. package/app/core/audit.py +30 -30
  12. package/app/core/backup.py +470 -470
  13. package/app/core/beekeeper.py +183 -183
  14. package/app/core/benchstore.py +102 -95
  15. package/app/core/board.py +246 -209
  16. package/app/core/bookmeta.py +1036 -1036
  17. package/app/core/bookmeta_catalog.py +180 -180
  18. package/app/core/branching.py +137 -137
  19. package/app/core/builtin_agent.py +2055 -1680
  20. package/app/core/capability.py +144 -144
  21. package/app/core/chaptersafe.py +32 -32
  22. package/app/core/checkpoints.py +648 -0
  23. package/app/core/cleanup.py +303 -303
  24. package/app/core/compaction.py +201 -201
  25. package/app/core/contracts.py +255 -255
  26. package/app/core/covergen.py +356 -356
  27. package/app/core/defectretro.py +43 -43
  28. package/app/core/diagnostics.py +114 -114
  29. package/app/core/dispatch.py +198 -191
  30. package/app/core/dispatch_log.py +128 -128
  31. package/app/core/env_scrub.py +85 -85
  32. package/app/core/errorlog.py +137 -137
  33. package/app/core/eval_matrix.py +82 -0
  34. package/app/core/evalbench.py +184 -91
  35. package/app/core/evaluation.py +174 -174
  36. package/app/core/failure_notify.py +290 -290
  37. package/app/core/flow_graph.py +33 -0
  38. package/app/core/goal_service.py +167 -167
  39. package/app/core/health.py +389 -389
  40. package/app/core/history.py +38 -38
  41. package/app/core/hooks.py +162 -162
  42. package/app/core/jobs.py +25 -4
  43. package/app/core/knowledge_pipeline.py +86 -0
  44. package/app/core/manager.py +2232 -2232
  45. package/app/core/mcp_client.py +200 -29
  46. package/app/core/mocks.py +64 -64
  47. package/app/core/notify.py +201 -201
  48. package/app/core/novel_quality.py +181 -189
  49. package/app/core/openapi.py +177 -154
  50. package/app/core/operations.py +228 -228
  51. package/app/core/paihang.py +145 -145
  52. package/app/core/pipeline.py +319 -59
  53. package/app/core/planner.py +17 -11
  54. package/app/core/policy.py +84 -0
  55. package/app/core/portguard.py +111 -111
  56. package/app/core/presence.py +77 -77
  57. package/app/core/preview.py +293 -293
  58. package/app/core/project_memory.py +139 -0
  59. package/app/core/prompt_guard.py +78 -78
  60. package/app/core/publish/__init__.py +7 -7
  61. package/app/core/publish/auto.py +106 -22
  62. package/app/core/publish/browser.py +694 -655
  63. package/app/core/publish/chaprows.py +138 -0
  64. package/app/core/publish/fanqie.py +212 -165
  65. package/app/core/publish/flow.py +832 -640
  66. package/app/core/publish/flows-fanqie-calibrated.json +361 -336
  67. package/app/core/publish/ledger.py +51 -2
  68. package/app/core/publish/manager.py +1150 -1118
  69. package/app/core/publish/qimao.py +176 -176
  70. package/app/core/publish/volumes.py +108 -0
  71. package/app/core/publish/ws.py +139 -139
  72. package/app/core/quality_gate.py +194 -194
  73. package/app/core/redact.py +38 -38
  74. package/app/core/repeat_guard.py +129 -129
  75. package/app/core/retrieval.py +137 -137
  76. package/app/core/router.py +398 -398
  77. package/app/core/runner.py +2239 -2238
  78. package/app/core/selfupdate.py +384 -384
  79. package/app/core/session_log.py +161 -161
  80. package/app/core/sessions.py +312 -312
  81. package/app/core/settings.py +33 -5
  82. package/app/core/settings_schema.py +282 -271
  83. package/app/core/share_page.py +114 -114
  84. package/app/core/skill_scan.py +139 -139
  85. package/app/core/skillpacks/fanqie-novel.md +8 -6
  86. package/app/core/skillpacks/market/character-bible.md +66 -66
  87. package/app/core/skillpacks/market/code-risk-checklist.md +58 -58
  88. package/app/core/skillpacks/market/git-workflow.md +57 -57
  89. package/app/core/skillpacks/market/release-notes.md +72 -72
  90. package/app/core/skillpacks/market/weekly-report.md +71 -71
  91. package/app/core/skillpacks/market/worldview-consistency.md +70 -70
  92. package/app/core/skillpacks/qimao-signing.md +14 -11
  93. package/app/core/skills.py +32 -21
  94. package/app/core/step_runner.py +132 -132
  95. package/app/core/store.py +24 -0
  96. package/app/core/story_tracking.py +275 -275
  97. package/app/core/task_compile.py +199 -199
  98. package/app/core/telemetry.py +292 -292
  99. package/app/core/tlsctx.py +64 -64
  100. package/app/core/token_meter.py +147 -147
  101. package/app/core/tool_outputs.py +107 -0
  102. package/app/core/tracing.py +207 -144
  103. package/app/core/upstream.py +41 -41
  104. package/app/core/usage.py +1038 -1038
  105. package/app/core/volumes.py +389 -389
  106. package/app/core/webhooks.py +89 -0
  107. package/app/core/wxdigest.py +865 -858
  108. package/app/core/zentao.py +2692 -2692
  109. package/app/main.py +179 -10
  110. package/app/mcp_server.py +244 -244
  111. package/app/pick_dialog.py +110 -110
  112. package/app/ui/app.js +563 -21
  113. package/app/ui/artdiff.js +74 -74
  114. package/app/ui/assets/community-qr.png +0 -0
  115. package/app/ui/assets/donate-alipay.jpg +0 -0
  116. package/app/ui/assets/donate-qr.jpg +0 -0
  117. package/app/ui/assets/workbench-reference.png +0 -0
  118. package/app/ui/board.css +451 -666
  119. package/app/ui/board.html +165 -162
  120. package/app/ui/board.js +509 -305
  121. package/app/ui/hive3d.js +242 -0
  122. package/app/ui/i18n.js +125 -9
  123. package/app/ui/icons/bee.svg +79 -79
  124. package/app/ui/index.html +60 -3
  125. package/app/ui/manifest.json +16 -16
  126. package/app/ui/qrcode.js +2297 -2297
  127. package/app/ui/style.css +189 -9
  128. package/bin/tutti.js +147 -147
  129. package/package.json +49 -48
  130. package/tools/wx_reader.py +261 -261
  131. package/app/.playwright-cli/console-2026-09-23T08-26-03-635Z.log +0 -88
  132. package/app/.playwright-cli/page-2026-09-23T08-26-03-845Z.yml +0 -126
  133. package/app/.playwright-cli/page-2026-09-23T08-29-44-203Z.png +0 -0
  134. package/app/.playwright-cli/page-2026-09-23T08-35-42-046Z.yml +0 -210
  135. package/app/.playwright-cli/page-2026-09-23T08-36-52-858Z.png +0 -0
  136. package/app/.playwright-cli/page-2026-09-23T08-37-33-938Z.png +0 -0
  137. package/app/.playwright-cli/run-detail-after.png +0 -0
  138. package/app/output/_createbook_body.json +0 -1
  139. package/app/output/_probe_fq_click.py +0 -50
  140. package/app/output/_probe_fq_form.py +0 -42
  141. package/app/output/_probe_fq_modal.py +0 -55
  142. package/app/output/_probe_fq_points.py +0 -71
  143. package/app/output/_probe_fq_submit.py +0 -34
  144. package/app/output/_probe_fq_watch.py +0 -62
package/app/ui/board.html CHANGED
@@ -1,162 +1,165 @@
1
- <!DOCTYPE html>
2
- <html lang="zh-CN" data-lang="zh">
3
- <head>
4
- <meta charset="utf-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
6
- <title>CodeBee · 任务驾驶舱</title>
7
- <link rel="icon" href="/icons/icon-192.png">
8
- <link rel="stylesheet" href="/board.css">
9
- </head>
10
- <body>
11
-
12
- <!-- 远程访问令牌门(本机免输;与主界面共用 orch.token) -->
13
- <div id="gate" class="gate hidden">
14
- <div class="gate-box">
15
- <div class="gate-mark" aria-hidden="true"><span></span><span></span><span></span></div>
16
- <div class="gate-title" data-i18n="需要访问令牌">需要访问令牌</div>
17
- <div class="gate-sub" data-i18n="启动 CodeBee 时控制台会显示">启动 CodeBee 时控制台会显示</div>
18
- <input id="gate-token" type="password" data-i18n-ph="访问令牌" placeholder="访问令牌" autocomplete="off">
19
- <button id="gate-ok" type="button" data-i18n="进入大屏">进入大屏</button>
20
- <div id="gate-err" class="gate-err"></div>
21
- </div>
22
- </div>
23
-
24
- <header id="hd">
25
- <div class="hd-brand">
26
- <div class="brand-mark" aria-hidden="true"><i></i><i></i><i></i><b></b></div>
27
- <div class="brand-copy">
28
- <div class="brand-kicker">CODEBEE / OPERATIONS</div>
29
- <div class="hd-name" data-i18n="任务驾驶舱">任务驾驶舱</div>
30
- </div>
31
- </div>
32
- <div class="hd-center">
33
- <span class="live-pip"></span>
34
- <span data-i18n="实时监控">实时监控</span>
35
- <span class="hd-sep">/</span>
36
- <span id="hd-updated" class="hd-updated" data-i18n="同步中">同步中</span>
37
- </div>
38
- <div class="hd-right">
39
- <div id="hd-pool" class="hd-pill" title="执行池占用" data-i18n-title="执行池占用">—</div>
40
- <div id="hd-health" class="hd-pill warn hidden" title=""></div>
41
- <div id="hd-conn" class="hd-pill off hidden" data-i18n="连接断开">连接断开</div>
42
- <div id="hd-clock" class="hd-clock">--:--:--</div>
43
- </div>
44
- </header>
45
-
46
- <main id="board">
47
- <section id="overview" class="overview panel">
48
- <div class="overview-copy">
49
- <div class="eyebrow"><span></span><span data-i18n="蜂群状态">蜂群状态</span></div>
50
- <div class="overview-line">
51
- <div>
52
- <h1 id="hero-state" data-i18n="蜂群待命">蜂群待命</h1>
53
- <p id="hero-copy" data-i18n="没有正在运行的任务,新任务在主界面创建后会实时出现在这里">没有正在运行的任务,新任务在主界面创建后会实时出现在这里</p>
54
- </div>
55
- <div class="hero-count">
56
- <strong id="hero-live-count">0</strong>
57
- <span data-i18n="个活动单元">个活动单元</span>
58
- </div>
59
- </div>
60
- <div class="overview-foot">
61
- <span class="signal-chip"><i></i><span id="hero-signal" data-i18n="系统状态良好">系统状态良好</span></span>
62
- <span class="overview-note" data-i18n="实时聚合 · 每 4 秒刷新">实时聚合 · 每 4 秒刷新</span>
63
- </div>
64
- </div>
65
- <div class="overview-visual" aria-hidden="true">
66
- <div class="orbit orbit-a"></div>
67
- <div class="orbit orbit-b"></div>
68
- <div class="orbit-dot dot-a"></div>
69
- <div class="orbit-dot dot-b"></div>
70
- <div class="orbit-dot dot-c"></div>
71
- <div class="core-glow"></div>
72
- <div class="overview-core"><strong id="orb-number">0</strong><span>ACTIVE</span></div>
73
- </div>
74
- <div class="overview-aside">
75
- <div class="aside-label" data-i18n="执行池">执行池</div>
76
- <div class="pool-meter"><i id="pool-meter-fill"></i></div>
77
- <div class="pool-readout"><strong id="pool-alive">0</strong><span>/</span><span id="pool-target">0</span><em data-i18n="在线槽位">在线槽位</em></div>
78
- <div class="aside-divider"></div>
79
- <div class="aside-row"><span data-i18n="队列等待">队列等待</span><b id="overview-queued">0</b></div>
80
- <div class="aside-row"><span data-i18n="今日成功率">今日成功率</span><b id="overview-success">—</b></div>
81
- </div>
82
- </section>
83
-
84
- <section id="kpis" aria-label="核心指标" data-i18n-aria="核心指标">
85
- <div class="kpi k-run">
86
- <div class="kpi-head"><span data-i18n="运行中">运行中</span><i class="kpi-icon"></i></div>
87
- <div class="k-num" id="k-running">0</div>
88
- <div class="kpi-foot"><span data-i18n="当前活动">当前活动</span><b>LIVE</b></div>
89
- </div>
90
- <div class="kpi k-queue">
91
- <div class="kpi-head"><span data-i18n="排队中">排队中</span><i class="kpi-icon"></i></div>
92
- <div class="k-num" id="k-queued">0</div>
93
- <div class="kpi-foot"><span data-i18n="等待调度">等待调度</span><b>QUEUE</b></div>
94
- </div>
95
- <div class="kpi k-done">
96
- <div class="kpi-head"><span data-i18n="今日完成">今日完成</span><i class="kpi-icon"></i></div>
97
- <div class="k-num" id="k-done">0</div>
98
- <div class="kpi-foot"><span data-i18n="完成运行">完成运行</span><b>DONE</b></div>
99
- </div>
100
- <div class="kpi k-fail">
101
- <div class="kpi-head"><span data-i18n="今日失败">今日失败</span><i class="kpi-icon"></i></div>
102
- <div class="k-num" id="k-failed">0</div>
103
- <div class="kpi-foot"><span data-i18n="需要关注">需要关注</span><b>ALERT</b></div>
104
- </div>
105
- <div class="kpi k-tok">
106
- <div class="kpi-head"><span data-i18n="今日 tokens">今日 tokens</span><i class="kpi-icon"></i></div>
107
- <div class="k-num" id="k-tokens">0</div>
108
- <div class="kpi-foot"><span data-i18n="模型消耗">模型消耗</span><b>USAGE</b></div>
109
- </div>
110
- <div class="kpi k-cost">
111
- <div class="kpi-head"><span data-i18n="今日成本">今日成本</span><i class="kpi-icon"></i></div>
112
- <div class="k-num" id="k-cost">$0.00</div>
113
- <div class="kpi-foot"><span data-i18n="运行成本">运行成本</span><b>COST</b></div>
114
- </div>
115
- </section>
116
-
117
- <section id="main">
118
- <section id="wall" class="panel live-panel">
119
- <header class="panel-head">
120
- <div>
121
- <div class="eyebrow"><span></span><span data-i18n="实时任务流">实时任务流</span></div>
122
- <h2 data-i18n="运行中任务">运行中任务</h2>
123
- </div>
124
- <div class="panel-head-right">
125
- <span id="wall-count" class="live-count">0 ACTIVE</span>
126
- <span id="wall-mode" class="mode-label" data-i18n="监控中">监控中</span>
127
- </div>
128
- </header>
129
- <div id="wall-cards"></div>
130
- <div id="wall-empty" class="wall-empty hidden">
131
- <div class="empty-orbit" aria-hidden="true"><i></i><i></i><i></i><b>0</b></div>
132
- <div class="idle-t1" data-i18n="队列已清空">队列已清空</div>
133
- <div class="idle-t2" data-i18n="等待新的任务接入蜂巢">等待新的任务接入蜂巢</div>
134
- <div class="empty-meta"><span><i></i><b data-i18n="工作池就绪">工作池就绪</b></span><span><i></i><b data-i18n="监控在线">监控在线</b></span></div>
135
- </div>
136
- <div id="queue-row" class="queue-row hidden">
137
- <div class="q-label"><span class="q-mark"></span><span data-i18n="排队等待">排队等待</span><b id="queue-count">0</b></div>
138
- <span id="queue-chips"></span>
139
- </div>
140
- </section>
141
-
142
- <aside id="rail">
143
- <section class="rail-card rail-trend panel">
144
- <div class="rail-head"><div><div class="eyebrow"><span></span><span data-i18n="资源脉冲">资源脉冲</span></div><h3 data-i18n="近 7 日 tokens">近 7 日 tokens</h3></div><span class="rail-badge">7 DAYS</span></div>
145
- <div id="trend" class="trend"></div>
146
- </section>
147
- <section class="rail-card rail-models panel">
148
- <div class="rail-head"><div><div class="eyebrow"><span></span><span data-i18n="模型分布">模型分布</span></div><h3 data-i18n="近 7 日模型 TOP5">近 7 日模型 TOP5</h3></div><span class="rail-badge">TOP 5</span></div>
149
- <div id="models" class="models"></div>
150
- </section>
151
- <section class="rail-card rail-recent panel grow">
152
- <div class="rail-head"><div><div class="eyebrow"><span></span><span data-i18n="事件日志">事件日志</span></div><h3 data-i18n="最近动态">最近动态</h3></div><span id="recent-count" class="rail-badge">—</span></div>
153
- <div id="recent" class="recent"></div>
154
- </section>
155
- </aside>
156
- </section>
157
- </main>
158
-
159
- <script src="/i18n.js"></script>
160
- <script src="/board.js"></script>
161
- </body>
162
- </html>
1
+ <!DOCTYPE html>
2
+ <html lang="zh-CN" data-lang="zh">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
6
+ <title>CodeBee · 任务驾驶舱</title>
7
+ <link rel="icon" href="/icons/icon-192.png">
8
+ <link rel="stylesheet" href="/board.css">
9
+ </head>
10
+ <body>
11
+
12
+ <!-- 远程访问令牌门(本机免输;与主界面共用 orch.token) -->
13
+ <div id="gate" class="gate hidden">
14
+ <div class="gate-box">
15
+ <div class="gate-title" data-i18n="需要访问令牌">需要访问令牌</div>
16
+ <div class="gate-sub" data-i18n="启动 CodeBee 时控制台会显示">启动 CodeBee 时控制台会显示</div>
17
+ <input id="gate-token" type="password" data-i18n-ph="访问令牌" placeholder="访问令牌" autocomplete="off">
18
+ <button id="gate-ok" type="button" data-i18n="进入大屏">进入大屏</button>
19
+ <div id="gate-err" class="gate-err"></div>
20
+ </div>
21
+ </div>
22
+
23
+ <header id="hd">
24
+ <div class="hd-brand"><div class="hd-name">CodeBee</div></div>
25
+
26
+ <div class="hd-state" id="hd-state">
27
+ <span class="state-pip" aria-hidden="true"></span>
28
+ <span class="state-text" id="hd-state-text" data-i18n="蜂群待命">蜂群待命</span>
29
+ <span class="hd-sep" aria-hidden="true"></span>
30
+ <span class="hd-sync" id="hd-updated" data-i18n="同步中">同步中</span>
31
+ </div>
32
+
33
+ <div class="hd-right">
34
+ <div class="hd-metric" data-i18n-title="执行池占用">
35
+ <em data-i18n="蜂巢">蜂巢</em><b id="hd-pool-alive">0</b><span id="hd-pool-target">/0</span>
36
+ </div>
37
+ <div class="hd-metric">
38
+ <em data-i18n="对话">对话</em><b id="hd-chat-alive">0</b><span id="hd-chat-pool">/0</span>
39
+ </div>
40
+ <div class="hd-svc" id="hd-health"><i aria-hidden="true"></i><span id="hd-health-text"></span></div>
41
+ <div id="hd-conn" class="hd-off hidden" data-i18n="连接断开">连接断开</div>
42
+ <div class="hd-swap">
43
+ <button class="sw-btn" id="sw-skin" type="button" data-i18n-title="切换皮肤(仅大屏记忆)"><span data-i18n="皮肤">皮肤</span> <b id="sw-skin-n">—</b></button>
44
+ <button class="sw-btn" id="sw-mode" type="button" data-i18n-title="切换明暗(仅大屏记忆)"><b id="sw-mode-n">—</b></button>
45
+ </div>
46
+ <div id="hd-clock" class="hd-clock">--:--:--</div>
47
+ </div>
48
+ </header>
49
+
50
+ <main id="board">
51
+
52
+ <section id="kpis" aria-label="核心指标" data-i18n-aria="核心指标">
53
+ <div class="kpi k-run">
54
+ <span class="k-lab" data-i18n="运行中">运行中</span>
55
+ <div class="k-row"><b class="k-num" id="k-running">0</b><span class="k-sub" id="k-run-sub">—</span></div>
56
+ </div>
57
+ <div class="kpi k-queue">
58
+ <span class="k-lab" data-i18n="排队中">排队中</span>
59
+ <div class="k-row"><b class="k-num" id="k-queued">0</b><span class="k-sub" id="k-queue-sub">—</span></div>
60
+ </div>
61
+ <div class="kpi k-done">
62
+ <span class="k-lab" data-i18n="今日完成">今日完成</span>
63
+ <div class="k-row"><b class="k-num" id="k-done">0</b><span class="k-sub" id="k-done-sub">—</span></div>
64
+ <span class="k-ratio" aria-hidden="true"><i id="k-ratio-fill"></i></span>
65
+ </div>
66
+ <div class="kpi k-fail">
67
+ <span class="k-lab" data-i18n="今日失败">今日失败</span>
68
+ <div class="k-row"><b class="k-num" id="k-failed">0</b><span class="k-sub" id="k-fail-sub">—</span></div>
69
+ </div>
70
+ <div class="kpi k-use">
71
+ <span class="k-lab" data-i18n="今日消耗">今日消耗</span>
72
+ <div class="k-row"><b class="k-num" id="k-tokens">0</b><span class="k-sub" id="k-use-sub">—</span></div>
73
+ </div>
74
+ </section>
75
+
76
+ <section id="main">
77
+ <section id="wall" class="panel">
78
+ <header class="p-head">
79
+ <h2 data-i18n="运行中任务">运行中任务</h2>
80
+ <div class="p-head-right">
81
+ <span id="wall-count" class="p-badge">0</span>
82
+ <span class="p-note" data-i18n="每 4 秒刷新">每 4 秒刷新</span>
83
+ </div>
84
+ </header>
85
+
86
+ <div id="wall-cards" class="wall-grid"></div>
87
+
88
+ <div id="wall-empty" class="wall-empty hidden">
89
+ <div class="idle-head">
90
+ <div class="idle-ring" aria-hidden="true"><i></i></div>
91
+ <div>
92
+ <div class="idle-t1" data-i18n="队列已清空">队列已清空</div>
93
+ <div class="idle-t2" data-i18n="新任务在主界面创建后会实时出现在这里">新任务在主界面创建后会实时出现在这里</div>
94
+ </div>
95
+ </div>
96
+ <div class="idle-list">
97
+ <div class="idle-cap"><span data-i18n="今日运行">今日运行</span> · <span id="idle-count">0</span> <span data-i18n="条">条</span></div>
98
+ <div id="idle-rows"></div>
99
+ </div>
100
+ </div>
101
+
102
+ <div id="queue-row" class="queue-row hidden">
103
+ <div class="q-label"><span data-i18n="排队等待">排队等待</span><b id="queue-count">0</b></div>
104
+ <span id="queue-chips"></span>
105
+ </div>
106
+ </section>
107
+
108
+ <aside id="rail">
109
+ <section class="rc rc-pool panel">
110
+ <div class="rc-head"><h3 data-i18n="执行池">执行池</h3><span class="rc-badge" id="pool-mode">—</span></div>
111
+ <div class="meter">
112
+ <div class="meter-top"><span data-i18n="蜂巢槽位">蜂巢槽位</span><b><i id="pool-alive">0</i>/<span id="pool-target">0</span></b></div>
113
+ <div class="meter-bar"><i id="pool-meter-fill"></i></div>
114
+ </div>
115
+ <div class="meter">
116
+ <div class="meter-top"><span data-i18n="对话槽位">对话槽位</span><b><i id="chat-alive">0</i>/<span id="chat-pool">0</span></b></div>
117
+ <div class="meter-bar cool"><i id="chat-meter-fill"></i></div>
118
+ </div>
119
+ <div class="pool-foot"><span data-i18n="空闲槽位">空闲槽位</span><b id="pool-available">0</b></div>
120
+ </section>
121
+
122
+ <section class="rc rc-trend panel">
123
+ <div class="rc-head"><h3 data-i18n="近 7 日 tokens">近 7 日 tokens</h3><span class="rc-badge" id="trend-total">—</span></div>
124
+ <div id="trend" class="trend"></div>
125
+ </section>
126
+
127
+ <section class="rc rc-models panel">
128
+ <div class="rc-head"><h3 data-i18n="近 7 日模型 TOP5">近 7 日模型 TOP5</h3><span class="rc-badge">TOP 5</span></div>
129
+ <div id="models" class="models"></div>
130
+ </section>
131
+
132
+ <section class="rc rc-recent panel">
133
+ <div class="rc-head"><h3 data-i18n="最近动态">最近动态</h3><span id="recent-count" class="rc-badge">—</span></div>
134
+ <div id="recent" class="recent"></div>
135
+ </section>
136
+ </aside>
137
+ </section>
138
+
139
+ </main>
140
+
141
+ <!-- 点运行卡下钻:步骤链取 /api/board/run,日志窗复用现成的 /api/runs/<id>/log -->
142
+ <div id="scrim"></div>
143
+ <aside id="drawer" aria-hidden="true">
144
+ <div class="dw-head">
145
+ <div class="dw-top">
146
+ <span class="c-type" id="dw-type"></span>
147
+ <h4 id="dw-title"></h4>
148
+ <button class="dw-close" id="dw-close" type="button" data-i18n-title="关闭 (Esc)">✕</button>
149
+ </div>
150
+ <p class="dw-goal" id="dw-goal"></p>
151
+ <div class="dw-meta" id="dw-meta"></div>
152
+ </div>
153
+ <div class="dw-body">
154
+ <div class="dw-steps" id="dw-steps"></div>
155
+ <div class="dw-log">
156
+ <div class="dw-log-head"><span class="tag" id="dw-log-tag" data-i18n="步骤日志">步骤日志</span><span id="dw-log-sub"></span></div>
157
+ <div class="dw-log-body" id="dw-log-body"></div>
158
+ </div>
159
+ </div>
160
+ </aside>
161
+
162
+ <script src="/i18n.js"></script>
163
+ <script src="/board.js"></script>
164
+ </body>
165
+ </html>