- 恢复清晰一级:总览/神兽/会话/活动/任务/协作/数据/消息/流水线/运维/飞轮/安全 - 总览瘦身:5 决策卡 + issues + 入口卡(想法/好奇链到飞轮·灵感) - 飞轮子导航 诊断|资源/LLM|灵感;运维/数据/活动保留分组 - 想法/好奇仅飞轮·灵感一处编辑;旧 hash 兼容
16 KiB
joy Web 面板 + joy CLI 架构收口方案
状态:MVP 已执行(Phase 0–3);布局修正:一级 tab 固定阈值 12(总览+11 功能),飞轮/运维/数据/活动子导航
日期:2026-07-09
确认:菲比斯「按你的方案来」(2026-07-09)
范围:~/Projects/joy-cli(主)+ 关联linuxjoy文档/watchdog 仅在必要时
原则:不横向加功能;收口、分层、对齐人机同源
已锁定决策
| 编号 | 选择 | 含义 |
|---|---|---|
| A1 | joy data 与现有 cluster-data 语义对齐 |
catalog/search/sql 同名;逻辑进 joy/core;非另起炉灶 |
| B1 | 默认首页 = 总览 | 不再默认神兽 |
| C1 | 执行序 0 → 1 → 3 → 2 → 4 | lite API 在 data 同源之后;Phase 4 后置 |
分工(执行时)
- 主代理:契约、TABS/路由、总览、三态、接口形状、联调验收
- 子代理:按卡搬 tab 合并、
cluster_data抽取、deprecated 转调、测试、Phase 4 拆分
0. 一句话目标
把 joy 从「55 命令 + 13 tab 的功能堆叠」收成:
- CLI = 飞轮运行时标准库(核心 ≤15 主命令,其余 deprecated/插件)
- Web = 给人的决策台(≤10 意图 tab,读多写少,写操作三态)
- 同源 = 数据资产 / Board / 健康信号 不在 web.py 与 CLI 各写一套
1. 背景与问题
1.1 已验证的合理分层(保留)
| 层 | 角色 | 形态 |
|---|---|---|
| joy CLI | agent / 脚本 | JSON、identity、可脚本 |
| joy web | 人 | 可见性 + 白名单写 |
| Board / NATS / dispatch | 集群执行 | web 不替代 |
1.2 当前痛点
| # | 问题 | 证据 |
|---|---|---|
| P1 | 面板 IA 按数据源堆叠 | 13 tab,运维 10 section,LLM 健康出现 3 处 |
| P2 | 写操作语义混杂 | 登记 / 轻量 route / 真 inject / 重建 不易区分 |
| P3 | 前端/采集单体 | app.js ~4800 行;dashboard.py ~2300 行;单 API 大象 |
| P4 | CLI 表面积过大 | ~55 顶级命令;README 与 help 漂移;大量重叠 |
| P5 | 人机不同源 | 数据资产检索逻辑在 web.py;CLI 无 joy data |
| P6 | 空壳稀释信任 | Langfuse 0 行曾与真探针并排 |
1.3 非目标(本方案不做)
- 重写整个 joy-cli 框架或换前端框架
- 把 Grafana 迁回主力
- 实现完整 dispatch inject 闭环(仅预留接口与标签)
- 改生产防火墙 / NATS ACL / 跨 VM 批量 prlctl
- 删除历史命令的 git 历史(只标 deprecated,软删入口)
2. 目标架构
2.1 三层契约(铁律)
┌─────────────────────────────────────────────────────────┐
│ 人(菲比斯 / 麟悦) │
│ joy web :8899 —— 读为主;写 = 白名单三态 │
└───────────────────────────┬─────────────────────────────┘
│ /api/* (lite + 分域)
┌───────────────────────────▼─────────────────────────────┐
│ joy CLI —— 飞轮标准库 │
│ A 核心运行时 B 领域扩展 C 遗留(deprecated) │
└───────────────────────────┬─────────────────────────────┘
│ board / journal / NATS / SSH
┌───────────────────────────▼─────────────────────────────┐
│ 集群执行面 Board · dispatch-loop · 神兽/work · VM │
└─────────────────────────────────────────────────────────┘
禁止:
- web 直接
prlctl批量 / 生产变更 - web action 绕过白名单
- 同一业务逻辑在
web.py与commands/*.py各维护一份
2.2 写操作三态(全局)
| 态 | 含义 | UI 标签 | 例子 |
|---|---|---|---|
| observe | 只读 / 刷新 | 灰 | 刷新缓存、journal last |
| register | 登记意图,不保证执行 | 黄 | board create、轻量 route |
| execute | 改变运行态,可破坏上下文 | 红 + 二次确认 | work_rebuild、clone restart、tmux restart |
规则:
- 每个按钮/action 必须标一态
- register 必须有可深链回执(task_id)
- execute 必须 confirm + audit log
- register ≠ inject(文案强制)
2.3 面板目标 IA(9 入口)
| # | Tab id | 中文 | 合并来源 | 默认 section |
|---|---|---|---|---|
| 1 | overview |
总览 | 现 Hero 强化,作为默认 tab | pulse / 瓶颈 / 关键 5 指标 |
| 2 | runtime |
运行 | 神兽 + 会话 + 活动 | 神兽列表;tmux;events |
| 3 | dispatch |
派活 | 任务 + 协作 + dispatch 队列 | 看板;组建团队;回执 |
| 4 | data |
数据 | 数据资产 + 知识库(次) | 检索+台账;记忆/cocobook section |
| 5 | messages |
消息 | 消息 | 现有 |
| 6 | pipelines |
流水线 | 流水线 | 现有 |
| 7 | ops |
运维 | 运维(已有 4 组) | 健康 | 网关 | 宿主机 | 名册 |
| 8 | analysis |
飞轮 | 飞轮诊断 + 资源路由 + 能力 | 七环;预算/容量;LLM |
| 9 | security |
安全 | 安全告警 | 告警;端口(默认非常见) |
从 13 → 9:去掉独立的 sessions/activity/collab/budget/memory/data-assets/flywheel-diag 一级入口,变为 section。
Hero:只在总览 tab 顶部;其它 tab 不再重复整块 hero(可保留 1 行 sticky 状态:stale / 失败率)。
关键 5 指标(总览固定):
- 健康
healthy/total - 分发失败率
failed/(completed+failed) - 瓶颈一句话
- 数据
searchable 库 / 总行 - Mac 负载·内存%
2.4 CLI 目标表面(核心 15)
| 主命令 | 职责 | 吸收/替代 |
|---|---|---|
help / tools |
发现 | — |
patrol |
单点/全景快检 | 部分 cluster_health 场景 |
health |
provider + self | — |
resources |
资源并行总览 | uptime/disk 作 sub 或 flag |
vm |
Parallels 电源 | prlctl → deprecated 指向 vm |
clone |
分身 | clone_restart → clone restart |
work |
work session | work_rebuild 作 sub |
tmux |
Mac 会话可观测 | — |
board |
Task Board | create/route/ls… |
journal |
记录+heartbeat | — |
message |
NATS | inbox/poke 保留但文档标「通信族」 |
recall |
集群记忆 | — |
data |
新建 数据资产 catalog/search | 与 web 同源 |
dashboard |
采集 | — |
web |
HTTP 服务 | — |
B 类保留(不进「核心 15」宣传,help 里第二段):
sop budget meter cocobook intel domain delegate curiosity daily konqi tux mind infra backup api config state who verify grow signal scan wake team profile project env output report bootstrap
C 类 deprecated(help 标废,半年后可删):
| 命令 | 迁移 |
|---|---|
prlctl |
joy vm |
clone_restart |
joy clone restart |
wake(若与 clone wake / vm wake 重复) |
文档指向明确 sub |
2.5 API 分层
| 端点 | 内容 | 刷新 |
|---|---|---|
GET /api/dashboard/lite |
ts, pulse, issues, flywheel 摘要, bottleneck, mac_host 摘要, stale | 10–15s |
GET /api/dashboard |
全量(兼容现前端) | 15–30s collect |
GET /api/tab/<name> |
可选懒加载:security / data_assets / pipelines | 按 tab |
| 现有 | /api/action /api/cluster-data/* /api/cocobook/* |
保持 |
Phase 1 可只加 lite,全量仍用现 API;Phase 2 再懒加载。
2.6 数据同源:joy data ≡ cluster-data(A1)
linuxjoy 已有 bash:scripts/cluster/cluster-data(catalog / show / sql / search)。
joy data catalog # 同 cluster-data catalog
joy data search <id> "<q>" # 同 cluster-data search
joy data sql <id> "<SQL>" # 同 cluster-data sql(可选 Phase 3)
joy data stats # 摘要(agent 省 token)
实现:
- 抽
joy/core/cluster_data.py(registry 解析 + search/sql SSH) commands/data.py+web.py共用同一 core- 禁止 web.py 再内嵌大段 py_script;bash
cluster-data可逐步改为调 joy 或双轨读同一 registry - 不另发明第二套资产 ID 或路径规则
2.7 Web 白名单分档
| 档 | 默认 | 命令例 |
|---|---|---|
| observe | 开 | dashboard --json, journal last |
| register | 开 | board create, board route(轻量), journal heartbeat, poke |
| execute | 开但强确认 | work_rebuild, clone restart, tmux restart, vm wake, docker * |
| control | 默认关 | board route --full, flywheel resume, 未来 prlctl kill |
控制:JOY_WEB_ALLOW_CONTROL=1 或配置文件开启。
3. 分阶段执行计划
Phase 0 — 契约落地(文档,0.5 天)
| 步骤 | 产出 | 验收 |
|---|---|---|
| 0.1 | 本方案合入 joy-cli docs/ + README 链到方案 |
文件存在 |
| 0.2 | README「命令一览」改为 核心15 + B/C 分层 | 与 help 不矛盾 |
| 0.3 | 写操作三态表写入 web.py 注释 + 前端常量 ACTION_TIER |
可查 |
不改运行行为。
Phase 1 — 面板 IA 收口(2–3 天)
| 步骤 | 内容 | 风险 |
|---|---|---|
| 1.1 | TABS 重组为 9 入口;hash 路由 #tab= 兼容旧 id 重定向 |
中:书签 |
| 1.2 | 总览 tab = 强化 Hero;其它 tab 去大 hero | 低 |
| 1.3 | 运行 = beasts+sessions+activity sections | 低 |
| 1.4 | 派活 = board+collab+dispatch | 低 |
| 1.5 | 数据 = data-assets + memory/sources 作 section | 中:知识库路径 |
| 1.6 | 飞轮 = flywheel-diag + budget | 低 |
| 1.7 | 全局 action 按钮三态样式(灰/黄/红) | 低 |
| 1.8 | cache bust;手动点检 9 tab | — |
兼容:旧 hash tab=beasts → runtime;tab=collab → dispatch 等映射表。
Phase 2 — API + 采集分频(1–2 天)
| 步骤 | 内容 |
|---|---|
| 2.1 | /api/dashboard/lite |
| 2.2 | 总览优先 lite;全量仍 15s watch |
| 2.3 | collect 内 security/data_assets 可 60s 缓存戳(可选) |
| 2.4 | Langfuse 空壳保持降级展示(已有则巩固) |
Phase 3 — CLI 收口 + data 同源(2 天)
| 步骤 | 内容 |
|---|---|
| 3.1 | joy/core/cluster_data.py 抽取 |
| 3.2 | `joy data catalog |
| 3.3 | web search/catalog 改调 core |
| 3.4 | prlctl / clone_restart help 标 deprecated,实现转调 |
| 3.5 | joy help 分组:核心 / 扩展 / 遗留 |
| 3.6 | pytest:data catalog 解析;deprecated 转调 smoke |
Phase 4 — 工程拆分(可并行,2–3 天)
| 步骤 | 内容 |
|---|---|
| 4.1 | src/joy/web/js/ 拆 tab 模块(build 可仍拼接或 ES modules) |
| 4.2 | dashboard.py 按 collect_* 文件拆 dashboard/ 包(可选) |
| 4.3 | 静态测试 + mac-collab 无关则只 joy-cli pytest |
Phase 4 可后置;1–3 完成后即可宣布「架构收口 MVP」。
4. 详细设计要点
4.1 旧 tab → 新 tab 映射
| 旧 id | 新 id | section |
|---|---|---|
| beasts | runtime | beasts |
| sessions | runtime | tmux |
| activity | runtime | events/journals/audit |
| board | dispatch | board-tasks, dispatch-hub |
| collab | dispatch | collab-compose, collab-matrix, 回执 |
| data-assets | data | da-hub |
| memory | data | memory-hub, sources-hub |
| messages | messages | — |
| pipelines | pipelines | — |
| monitoring | ops | 四组不变 |
| flywheel-diag | analysis | fly-* cap2-* |
| budget | analysis | budget/cap/llm |
| security | security | — |
| (新)overview | overview | hero 指标 |
4.2 joy data 行为
joy data catalog
→ { assets, total_rows, total_assets, by_type, by_vm, searchable, archive, registry }
joy data search --asset ailab-mbawiki --query "品牌定位" [--limit 5]
→ { query, asset, results: [{distance, text, title, url}] }
joy data stats
→ 摘要数字(给 agent 省 token)
Registry 路径优先级(与现 collect 一致):
~/Projects/linuxjoy/configs/cluster-data-registry.yml~/mnt/shared-context/cluster-data-registry.yml/mnt/shared-context/cluster-data-registry.yml
4.3 前端模块边界(Phase 4)
src/joy/web/
index.html
styles.css
app.js # 壳:路由、load、action、TABS 注册
js/
api.js
actions.js # doActionRaw + 三态
tabs/
overview.js
runtime.js
dispatch.js
data.js
ops.js
analysis.js
security.js
messages.js
pipelines.js
MVP 可用 IIFE + 顺序 script 标签,不强制打包器。
4.4 测试与验收
| 项 | 命令/方法 |
|---|---|
| 语法 | py_compile + node --check |
| 单测 | pytest tests/(现有 14+;data 新增 2–3) |
| 面板 | 9 tab 手动点检;深链 #tab=dispatch&task=BT- |
| CLI | joy data catalog | jq .total_assets;joy prlctl 转调提示 |
| 回归 | journal_stale 不被错误抬高;lite 与 full ts 一致 |
4.5 回滚
- 仅 git revert 对应 commit
- tab 映射保留旧 id 一周
/api/dashboard全量不删,lite 失败则回退 full
5. 工作量与依赖
| Phase | 估时 | 依赖 |
|---|---|---|
| 0 文档 | 0.5d | 无 |
| 1 面板 IA | 2–3d | 0 |
| 2 lite API | 1–2d | 1 可并行后半 |
| 3 CLI data | 2d | 与 1 可并行 |
| 4 拆分 | 2–3d | 1+3 后 |
合计 MVP(0–3):约 5–7 人日。
6. 风险与缓解
| 风险 | 影响 | 缓解 |
|---|---|---|
| 用户习惯旧 tab 名 | 找不到 | hash 重定向 + 一周内双显示 tip |
| 合并后 section 过多 | 仍刷屏 | 运维/飞轮保持子导航 |
joy data search 慢 |
SSH+ollama | 超时 40s 保持;错误明文 |
| deprecated 仍被脚本调用 | 破脚本 | 转调兼容,不立刻 delete |
| 白名单 control 误关 | 运维不便 | 默认 execute 仍开;仅 full route 进 control |
| 大 PR 难审 | 返工 | 严格按 Phase 提交 |
7. 成功标准(MVP = Phase 0–3)
- 一级 tab ≤ 10,默认进入 总览
- 写操作可见三态;协作 register/route 文案与代码一致
joy data catalog与面板资产数一致joy help核心段 ≤ 20 行主命令;deprecated 可发现- README 与 help 不再互相打架
- pytest 全绿;手动 9 tab 无白屏
8. 评审清单
- 9 tab IA 按意图(已确认)
- A1:
joy data≡cluster-data语义(已确认) - B1:默认总览(已确认)
- C1:0→1→3→2→4(已确认)
- 轻量 route 保持默认
- Phase 4 后置,不进 MVP 强制范围
- 本轮不强制改 linuxjoy watchdog(除非 journal 相关已改过)
9. 建议执行顺序(确认后)
Phase 0 文档契约
↓
Phase 1 面板 IA(人立刻感到变清爽)
↓
Phase 3 joy data 同源 + CLI deprecated(人机对齐)
↓
Phase 2 lite API(性能)
↓
Phase 4 拆分(可另开迭代)
10. 变更影响面
| 路径 | Phase |
|---|---|
src/joy/web/app.js index.html styles.css |
1, 4 |
src/joy/commands/web.py |
1–3 |
src/joy/commands/dashboard.py |
2 |
src/joy/core/cluster_data.py 新建 |
3 |
src/joy/commands/data.py 新建 |
3 |
src/joy/commands/prlctl.py clone_restart.py |
3 |
src/joy/commands/help.py README.md |
0, 3 |
docs/joy-panel-cli-architecture-plan.md |
0 |
文档结束。下一步:评审(见会话内评审意见)→ 你确认 → 按 Phase 0 开工。