Phase 0–7 of docs/joy-cli-hardening-plan.md: - golden fixtures + contract tests (commands/dashboard keys/whitelist) - command tier metadata; help ≡ manifest (pipeline in core) - _joy.schema_version on dict outputs; dashboard collect package split - work_rebuild → shared rebuild; deprecated markers; journal vm-first compat - web JSONL audit; lazy command import; plugins README
521 lines
22 KiB
Markdown
521 lines
22 KiB
Markdown
# joy-cli 长期硬化完整方案(兼容三员 / 神兽 / joy web)
|
||
|
||
> **状态**:**Phase 0–7 已执行**(2026-07-10);持续维护见修订表
|
||
> **日期**:2026-07-10
|
||
> **范围**:`~/Projects/joy-cli` 主仓;关联 `linuxjoy` 文档/生成模板、`~/office/*/CLAUDE.md|AGENTS.md`、launchd `joy.web` / `joy.dashboard`
|
||
> **原则**:**不破坏在飞轮上的用法**;可删入口只能 **deprecated 转发**,不能 silent 删;一切破坏性变更必须带契约测试与回归清单
|
||
|
||
---
|
||
|
||
## 0. 为什么要改(问题浓缩)
|
||
|
||
| # | 问题 | 风险 |
|
||
|---|------|------|
|
||
| P1 | 顶级命令 **58**,agent 发现成本高 | 神兽/三员 prompt 与 help 漂移 |
|
||
| P2 | `dashboard.py` **~3.2k 行** 单体 | 改一处牵全身;回归靠人眼 |
|
||
| P3 | help / manifest 不同源(已出现 `pipeline` 漂移) | AI 发现层不可信 |
|
||
| P4 | JSON **无 schema_version** | 静默破坏 web/agent 解析 |
|
||
| P5 | 权限元数据存在但几乎未启用 | 误用 execute 难追责 |
|
||
| P6 | web 白名单含 execute,audit 弱 | 本机决策台误操作成本高 |
|
||
| P7 | 测试以 smoke 为主 | 「46 绿」≠ 飞轮语义正确 |
|
||
|
||
**本方案不是功能扩张**,是:收口、契约化、可维护、可回归。
|
||
|
||
---
|
||
|
||
## 1. 在飞轮里的真实调用面(改前必知)
|
||
|
||
### 1.1 常驻进程(Mac launchd)
|
||
|
||
| Label | 命令 | 依赖 |
|
||
|-------|------|------|
|
||
| `joy.dashboard` | `joy dashboard --watch` | 写 `/tmp/joy-dashboard.json`;**字段形状是 web 真源** |
|
||
| `joy.web` | `joy web` | 读 cache + `/api/*` + 白名单 action;前端 `src/joy/web/**` |
|
||
|
||
> 改 `dashboard`/`web` 等于改生产观测面。必须 **热替换后验 cache keys + HTTP + 前端关键 tab**。
|
||
|
||
### 1.2 三位管理员(Mac office)
|
||
|
||
| 角色 | 身份检测 | 文档写明的高频 joy 命令 | 影响敏感度 |
|
||
|------|----------|-------------------------|------------|
|
||
| **konqi 龙奇** | `JOY_IDENTITY` / cwd `office/konqi` / 进程启发式 | `joy konqi *`、`patrol`、`cluster-health`、`clone *`、`board`、`recall`、`poke`、`message`、`mind`、`tmux`、`infra`、`api`、`prlctl`、`work_rebuild`、`clone_restart`、`restart clones` | **极高** |
|
||
| **tux 塔司** | office/tux + opencode | `joy tux *`、`patrol`、`profile`、`board`、`recall`、`poke`、`message`、`mind`、`api probe` | **极高** |
|
||
| **wapuu** | office/wapuu | `joy intel`、`db`、`domain`、`board`、`recall`、`poke`、`message`、`mind` | **高** |
|
||
|
||
来源:`~/office/{konqi,tux,wapuu}/{AGENTS,CLAUDE}.md`。
|
||
|
||
### 1.3 神兽(16 joy-clones pi)
|
||
|
||
**启动模板真源**:`linuxjoy/scripts/mac/joy-clones.sh` 写入各 `~/office/<vm>/CLAUDE.md` 技术段。
|
||
|
||
神兽标准工具链(每台 VM 同构):
|
||
|
||
```text
|
||
joy patrol <vm>
|
||
joy profile <vm>
|
||
joy project <vm>
|
||
joy curiosity <vm>
|
||
joy work <vm> transcript|inject|alive|idle
|
||
joy journal <vm> write|last|doubts
|
||
joy board ls|claim|done
|
||
joy recall search|add
|
||
joy signal stuck|done|help
|
||
joy delegate / joy who / joy env / joy inbox
|
||
joy budget <vm>
|
||
```
|
||
|
||
> **神兽不依赖 joy web**;依赖 **CLI JSON 形状 + 子命令名**。
|
||
> 改名只能:旧命令保留转发;或同步改 `joy-clones.sh` 模板并 **rebuild 16 路 CLAUDE.md**。
|
||
|
||
### 1.4 人 / 菲比斯
|
||
|
||
- 浏览器 `http://localhost:8899`(joy web)
|
||
- 偶发 CLI:`joy help`、`joy dashboard`、`joy board`、`joy web`
|
||
|
||
### 1.5 当前 dashboard JSON 顶层键(兼容红线)
|
||
|
||
实测 `/tmp/joy-dashboard.json` 顶层(**禁止无版本迁移就删/改名**):
|
||
|
||
```text
|
||
audit_ledger, board_tasks, bottleneck, bridge, capabilities, collect_errors,
|
||
curiosity, data_assets, dispatch_queue, events, flywheel, health_grid, ideas,
|
||
infra, issues, llm_providers, mac_host, meter, monitoring, nats, new_api,
|
||
physical_hosts, pi_agents, pipelines, pulse, security, tmux, trends, ts, vms
|
||
```
|
||
|
||
前端 tabs 与 hero 按这些键投影。**拆 dashboard 文件时必须 golden 对比顶层键集合**。
|
||
|
||
---
|
||
|
||
## 2. 影响矩阵(改完会不会影响)
|
||
|
||
### 2.1 总原则
|
||
|
||
| 变更类型 | 对 web | 对三员 | 对神兽 | 策略 |
|
||
|----------|--------|--------|--------|------|
|
||
| 物理拆分 `dashboard.py`(行为不变) | 无感 | 无感 | 无感 | 优先做 |
|
||
| help/manifest 同源 + 补 pipeline | 无感 | 发现更好 | 发现更好 | 优先做 |
|
||
| JSON 加 `schema_version`(**附加字段**) | 无感* | 无感* | 无感* | 附加不删 |
|
||
| 旧命令 **deprecated 转发**(stdout 多 `deprecated` 字段) | 无感 | **兼容** | **兼容** | 允许 |
|
||
| 删除顶级命令入口 | 可能破 web action | **会破 AGENTS** | **会破 16 CLAUDE** | **禁止本阶段** |
|
||
| 改子命令语义/字段改名 | 破 tab | 破解析 | 破解析 | 仅 schema_version bump + 双写过渡 |
|
||
| 收紧 web control 默认 | 部分按钮需确认/失败 | CLI 不受 | 不受 | 可做,需 UI 文案 |
|
||
| 懒加载命令 import | 冷启动变快 | 无感 | 无感 | 可做,manifest 全量仍要加载 |
|
||
|
||
\*若某 agent 用「对象键集合严格相等」解析会炸——实测 joy 侧均按字段读取,**附加字段安全**。
|
||
|
||
### 2.2 明确「不会动」的 ABI(冻结列表)
|
||
|
||
下列 **命令路径 + 关键字段** 本阶段冻结;只允许 bugfix 与附加字段:
|
||
|
||
#### A. 神兽日用 ABI
|
||
|
||
| 命令 | 冻结点 |
|
||
|------|--------|
|
||
| `joy patrol <vm>` | 顶层含 session/activity/board/inbox/doubts/llm 类信息(允许附加) |
|
||
| `joy work <vm> {transcript,inject,alive,idle}` | 子命令名;inject 字符串参数 |
|
||
| `joy journal <vm> write\|last\|doubts` | 路径与写 journal.jsonl 行为 |
|
||
| `joy board ls\|claim\|done\|create\|route` | 子命令名;task id 语义 |
|
||
| `joy recall search\|add` | 子命令存在 |
|
||
| `joy signal` / `joy inbox` / `joy budget` | 入口存在 |
|
||
| `joy profile` / `joy project` / `joy curiosity` / `joy env` / `joy who` / `joy delegate` | 入口存在 |
|
||
|
||
#### B. 三员日用 ABI
|
||
|
||
| 角色 | 冻结 |
|
||
|------|------|
|
||
| konqi | `joy konqi *`、`clone *`、`tmux`、`infra`、`api`、`poke`、`mind`、`restart`、`work_rebuild`、`clone_restart`、`prlctl` |
|
||
| tux | `joy tux *`、`patrol`、`profile`、`board`、`poke` |
|
||
| wapuu | `joy intel`、`db`、`domain`、`board` |
|
||
|
||
#### C. joy web / dashboard ABI
|
||
|
||
| 契约 | 冻结 |
|
||
|------|------|
|
||
| `GET /api/dashboard` | 返回与 cache 同形;顶层键集合 ⊇ 现状 |
|
||
| `GET /api/dashboard/lite` | 保留 |
|
||
| `POST /api/action` | 白名单前缀兼容;args 数组形态 |
|
||
| `ACTION_WHITELIST` 已有前缀 | **不删**;可增不可减(本阶段) |
|
||
| `/tmp/joy-dashboard.json` 路径 | 不改 |
|
||
| launchd 参数 `joy dashboard --watch` / `joy web` | 不改 |
|
||
|
||
#### D. 身份环境变量
|
||
|
||
- `JOY_IDENTITY` 优先逻辑保留
|
||
- `PYTHONPATH=.../joy-cli/src` launchd 注入保留
|
||
- `~/bin/joy` → `Projects/joy-cli/bin/joy` 符号链接保留
|
||
|
||
---
|
||
|
||
## 3. 目标架构(长期)
|
||
|
||
```
|
||
┌─ 人:joy web :8899 ─────────────────────────────────────┐
|
||
│ 读 /api/dashboard(+lite) 写 /api/action(三态+audit) │
|
||
└───────────────────────────┬─────────────────────────────┘
|
||
│ 同源
|
||
┌───────────────────────────▼─────────────────────────────┐
|
||
│ joy CLI = 飞轮 agent ABI(稳定) │
|
||
│ A 核心运行时 B 领域扩展 C deprecated 转发 │
|
||
│ tools --manifest ≡ help 同源 │
|
||
└───────────────────────────┬─────────────────────────────┘
|
||
│ façade
|
||
┌───────────────────────────▼─────────────────────────────┐
|
||
│ linuxjoy scripts / Board / NATS / prlctl / SSH │
|
||
└─────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
**CLI 表面分层(元数据,不是删命令)**
|
||
|
||
| tier | 含义 | 示例 |
|
||
|------|------|------|
|
||
| **core** | 日常 ABI,help 默认展示 | patrol, health, resources, vm, clone, work, tmux, board, journal, message, recall, data, pipeline, idea, dashboard, web, tools, help |
|
||
| **extended** | 领域/角色扩展 | konqi, tux, mind, intel, budget, profile… |
|
||
| **deprecated** | 仍可用,help 标废,JSON 可带 `deprecated` | prlctl, clone_restart, work_rebuild(转发 work rebuild) |
|
||
|
||
> 核心数量以 **help 展示收口** 为主;**注册表仍保留全部 58**,避免神兽/旧 AGENTS 断裂。
|
||
|
||
---
|
||
|
||
## 4. 分阶段执行计划(可验收)
|
||
|
||
### Phase 0 — 契约冻结与基线(0.5–1 天)
|
||
|
||
**动作**
|
||
|
||
1. 本文件入库(`docs/joy-cli-hardening-plan.md`)
|
||
2. 建立 **golden 基线**(只读采集,不改代码逻辑):
|
||
- `tests/fixtures/dashboard_keys_v1.json`:顶层键列表
|
||
- `tests/fixtures/command_inventory_v1.json`:58 命令名 + requires/env
|
||
- `tests/fixtures/web_action_prefixes_v1.json`:白名单前缀
|
||
3. 文档化消费者矩阵(§1)进 README 链
|
||
4. 工作区未提交改动:**先 stash/提交归类**,避免硬化过程混入 hardware 等半成品
|
||
|
||
**验收**
|
||
|
||
- [ ] golden 文件存在且 CI/本地测试可读
|
||
- [ ] `pytest` 现网 46 绿仍过
|
||
|
||
**影响**:无。
|
||
|
||
---
|
||
|
||
### Phase 1 — 发现层与元数据同源(0.5–1 天)**【低风险 · 先做】**
|
||
|
||
**动作**
|
||
|
||
1. `@command` 增加字段:
|
||
- `tier: core|extended|deprecated`
|
||
- `schema_version`(命令级可选)
|
||
- `replaced_by`(deprecated 用)
|
||
2. `HELP_DATA` **从 COMMANDS 生成**(或生成后 diff 强制一致)
|
||
3. 补齐 `pipeline` 进入 help/core
|
||
4. `tools --manifest` 输出含 `tier`、`schema_version`、`identity`
|
||
5. 测试:`test_manifest_help_sync.py` — 注册集 == help 集;pipeline 在 core
|
||
|
||
**验收**
|
||
|
||
- [ ] `joy help --json` 含 pipeline
|
||
- [ ] `joy tools --manifest | jq '.commands|length'` ≥ 现网
|
||
- [ ] 无命令从注册表消失
|
||
|
||
**影响**:无功能影响;三员/神兽 `joy help` 更准。
|
||
|
||
---
|
||
|
||
### Phase 2 — JSON 契约版本化(1 天)**【低风险】**
|
||
|
||
**动作**
|
||
|
||
1. 统一成功输出包装策略(**双轨,兼容优先**):
|
||
- 对「本已是 dict」的响应:**附加** `"schema_version": 1`(或 `"_joy": {"schema_version":1}` 若担心冲突)
|
||
- 推荐 **`_joy.schema_version`** 命名空间,避免污染业务字段
|
||
2. 优先覆盖:`dashboard` cache、`patrol`、`board ls`、`tools --manifest`、`data *`、`pipeline *`、`health`
|
||
3. 错误 JSON 保持 `{error, code, detail?}` 不变
|
||
|
||
**验收**
|
||
|
||
- [ ] 旧解析(读业务字段)仍通过
|
||
- [ ] 新测试 assert `_joy.schema_version` 或顶层附加字段存在
|
||
- [ ] `/tmp/joy-dashboard.json` 仍含全部旧顶层键
|
||
|
||
**影响**:web 前端忽略未知字段 → **无感**。
|
||
|
||
---
|
||
|
||
### Phase 3 — dashboard 物理拆分(1–2 天)**【中风险 · 行为冻结】**
|
||
|
||
**目标**:`dashboard.py` 从 3k 行降到「编排壳 + collect 模块」,**输出字节级语义不变**(允许键序/空白差)。
|
||
|
||
**建议目录**
|
||
|
||
```text
|
||
src/joy/commands/dashboard.py # CLI 入口 + compose + --watch
|
||
src/joy/dashboard/
|
||
__init__.py
|
||
compose.py # 拼总 dict + 写 cache
|
||
schema.py # 顶层键常量 + schema_version
|
||
collectors/
|
||
mac_host.py
|
||
tmux_pi.py
|
||
vms_health.py
|
||
board_dispatch.py
|
||
llm_gateway.py
|
||
data_assets.py
|
||
pipelines.py
|
||
security_infra.py
|
||
...
|
||
```
|
||
|
||
**硬规则**
|
||
|
||
1. **禁止**本阶段改 collector 业务算法(除明确 bug)
|
||
2. 每拆一块:`pytest` + **golden keys** + 可选 `joy dashboard --json | jq 'keys'` 对比
|
||
3. 去掉 `shell=True` 时改为 argv 列表,**对比 stdout 再合**
|
||
4. launchd `joy.dashboard` 不改参数;拆完后 `launchctl kickstart -k gui/$UID/joy.dashboard` 验证
|
||
|
||
**验收**
|
||
|
||
- [ ] 顶层键集合 == golden
|
||
- [ ] `pulse/bottleneck/vms/pi_agents/pipelines/data_assets` 抽样字段类型不变
|
||
- [ ] `joy.dashboard` KeepAlive 稳定 ≥ 2 个 watch 周期
|
||
- [ ] web 总览 / 神兽 / 任务 / 流水线 / 数据 tab 人工点检
|
||
|
||
**影响**:若 compose 漏字段 → **web 破**。用 golden 挡。
|
||
|
||
---
|
||
|
||
### Phase 4 — deprecated 转发(不删入口)(0.5–1 天)**【中风险 · 兼容】**
|
||
|
||
**只做转发,不做删除**:
|
||
|
||
| 旧入口 | 转发到 | 额外 |
|
||
|--------|--------|------|
|
||
| `joy prlctl ...` | `joy vm ...`(已有) | 确保 help 标废 |
|
||
| `joy clone_restart <vm>` | `joy clone restart <vm>` | 已有,补测 |
|
||
| `joy work_rebuild <vm>` | `joy work <vm> rebuild`(**新增 sub**,旧入口保留) | 双入口 |
|
||
| (可选)`joy uptime` / `joy disk` | 内部调 `resources` 同数据 | 入口保留 |
|
||
|
||
**禁止本阶段**
|
||
|
||
- 删除 `work_rebuild` 顶级名(konqi CLAUDE 仍写它)
|
||
- 删除 `prlctl` / `clone_restart`
|
||
|
||
**同步文档(非阻断)**
|
||
|
||
- 更新 `linuxjoy/docs/tools/joy-cli-reference.md`
|
||
- 更新 `office/konqi/CLAUDE.md` 推荐新写法,**旧写法仍可用**
|
||
|
||
**验收**
|
||
|
||
- [ ] 旧命令 exit 0 行为与新命令一致(同 vm 测)
|
||
- [ ] 响应可含 `"deprecated": "use joy ..."` 但不影响主字段
|
||
|
||
**影响**:三员旧 prompt **继续工作**。
|
||
|
||
---
|
||
|
||
### Phase 5 — web 可追责与 action 统一(1–2 天)**【中风险】**
|
||
|
||
**动作**
|
||
|
||
1. `/api/action` 统一路径:
|
||
`parse args → tier_for_args → whitelist → (control 门闩) → 调 joy CLI 同进程/子进程 → audit append`
|
||
2. audit:`~/logs/joy-web-audit.jsonl` 或 `/tmp`+NAS 可选;字段:ts, identity, tier, args, rc, ms, err_snip
|
||
3. UI:execute 二次确认文案统一;control 默认关(已有则加固)
|
||
4. **不删** 现有白名单前缀
|
||
|
||
**验收**
|
||
|
||
- [ ] `test_web_action_whitelist` 扩展:非法前缀 403/拒绝
|
||
- [ ] 合法 `patrol devops` / `idea list` / `board ls` 类 observe/register 可用
|
||
- [ ] audit 文件有追加
|
||
- [ ] 前端按钮仍能点通 3 个代表动作
|
||
|
||
**影响**:人用 web 更安全;CLI 与神兽 **不受影响**。
|
||
|
||
---
|
||
|
||
### Phase 6 — 运行时质量(懒加载 / Env / 清理)(1 天)**【低–中】**
|
||
|
||
1. **懒加载**:`main` 仅 import 目标 command 模块;`tools --manifest` / `help` 才全量 import
|
||
2. `Env` 支持测试注入(不改 singleton 对外行为)
|
||
3. inventory 失败:**stderr 诊断 + 明确 fallback 列表**,不 silent
|
||
4. 删除空目录 `commands/`、`lib/`;`domains/*.sh` → `archive/domains/`(确认无引用)
|
||
5. `plugins/` 写 README:实验命令准入规则
|
||
|
||
**验收**
|
||
|
||
- [ ] `time joy help` 不劣化;`time joy patrol` 可改善或持平
|
||
- [ ] 全量 pytest 绿
|
||
|
||
**影响**:应无感;若懒加载漏注册 → 命令「未知」——用 manifest 测试挡。
|
||
|
||
---
|
||
|
||
### Phase 7 — 测试金字塔与发布门禁(贯穿 + 收尾 1 天)
|
||
|
||
#### 7.1 测试分层
|
||
|
||
| 层 | 内容 | 门禁 |
|
||
|----|------|------|
|
||
| L0 静态 | `python -m compileall src/joy` | 必过 |
|
||
| L1 unit | cluster_data, pipeline_registry, action_tiers, env identity | 必过 |
|
||
| L2 contract | manifest↔help;dashboard keys golden;web whitelist golden;schema_version | 必过 |
|
||
| L3 smoke CLI | 每条 **core** 命令 `--help` 或无参不崩;JSON 错误形态 | 必过 |
|
||
| L4 integration | board ls / data catalog / pipeline list(NAS 在则跑,不在则 skip) | 尽力 |
|
||
| L5 live Mac | dashboard --json keys;curl web lite/dashboard;launchd 状态 | 发布前必做 |
|
||
| L6 agent 回归 | 见 §5 检查单 | 发布前必做 |
|
||
|
||
#### 7.2 发布检查单(Definition of Done)
|
||
|
||
```text
|
||
[ ] pytest 全绿(新增 contract 全过)
|
||
[ ] golden:commands 集合未减少
|
||
[ ] golden:dashboard 顶层键未减少
|
||
[ ] golden:web action 前缀未减少
|
||
[ ] joy help 含 pipeline;tools --manifest 与 help 一致
|
||
[ ] launchctl print joy.dashboard / joy.web 为 running
|
||
[ ] curl -s localhost:8899/ | head 200
|
||
[ ] curl -s localhost:8899/api/dashboard/lite 含 pulse/ts
|
||
[ ] /tmp/joy-dashboard.json 新鲜(ts 在 2min 内)
|
||
[ ] 人工:web 总览、神兽、任务、流水线、数据 tab 无空白/JS 错
|
||
[ ] 代表 CLI:
|
||
JOY_IDENTITY=konqi joy konqi overview | head
|
||
JOY_IDENTITY=tux joy tux pending | head
|
||
JOY_IDENTITY=wapuu joy intel brief | head # 或 domains
|
||
joy patrol devops | head
|
||
joy board ls | head
|
||
joy clone status | head
|
||
joy work devops alive | head
|
||
[ ] 神兽模板:joy-clones.sh 技术段命令仍全部可执行(抽 1 台 devops)
|
||
[ ] 未改 JOY_IDENTITY / ~/bin/joy / launchd ProgramArguments
|
||
```
|
||
|
||
#### 7.3 回滚
|
||
|
||
| 场景 | 回滚 |
|
||
|------|------|
|
||
| dashboard 采集坏 | `git revert` 对应 commit;`launchctl kickstart -k gui/$UID/joy.dashboard` |
|
||
| web 起不来 | 同上 + `kickstart joy.web` |
|
||
| 命令丢失 | 禁止出现;若出现从 git 恢复 `commands/*.py` |
|
||
| 半成品分支 | 功能开关:无(本阶段不做大开关);用 git 回滚 |
|
||
|
||
---
|
||
|
||
## 5. 消费者回归检查单(详细)
|
||
|
||
### 5.1 joy web
|
||
|
||
| 检查 | 方法 | 期望 |
|
||
|------|------|------|
|
||
| 服务存活 | `launchctl list \| rg joy.web` | PID 在 |
|
||
| 首页 | 浏览器 :8899 | 总览有 pulse |
|
||
| lite API | `curl /api/dashboard/lite` | 200 + ts |
|
||
| 全量 API | `curl /api/dashboard \| jq 'keys'` | ⊇ golden |
|
||
| 白名单列表 | `curl /api/actions` | 前缀齐全 |
|
||
| 写操作 | UI:idea list / journal last / patrol 单 VM | 成功或明确错误 JSON |
|
||
| 样式/JS | DevTools Console | 无硬错误 |
|
||
|
||
### 5.2 三员
|
||
|
||
| 角色 | 命令烟测 | 权限烟测 |
|
||
|------|----------|----------|
|
||
| konqi | `JOY_IDENTITY=konqi joy konqi overview` | `JOY_IDENTITY=wenpai joy konqi overview` → E_PERM |
|
||
| tux | `JOY_IDENTITY=tux joy tux pending` | 非 tux → E_PERM |
|
||
| wapuu | `JOY_IDENTITY=wapuu joy board ls` | 可用 |
|
||
| 通信 | `joy poke` dry 路径(避免真注入可 mock/短消息) | requires 含三员 |
|
||
| 旧名 | `joy work_rebuild` / `joy clone_restart` / `joy prlctl` | 仍可用或明确转发 |
|
||
|
||
### 5.3 神兽
|
||
|
||
| 检查 | 方法 |
|
||
|------|------|
|
||
| 模板命令可运行 | 对 `devops` 跑 joy-clones 技术段每一条(read-only 优先) |
|
||
| journal 写 | `joy journal devops last 1` |
|
||
| work 观测 | `joy work devops alive` / `transcript 3` |
|
||
| board | `joy board ls --vm devops` |
|
||
| 不依赖 web | 断 web 后 CLI 仍可用(可临时停 joy.web 再启) |
|
||
| rebuild 策略 | **默认不 rebuild 16 神兽**;仅当改 CLAUDE 模板时才 `joy-clones` 重生配置 |
|
||
|
||
### 5.4 VM 上 joy(若已 deploy)
|
||
|
||
| 检查 | 方法 |
|
||
|------|------|
|
||
| 存在 | `ssh devops 'joy --version'` |
|
||
| 基础 | `ssh devops 'joy help \| head'` |
|
||
| 与 Mac 差集 | VM 无 prlctl/web/dashboard 属预期(env 限制) |
|
||
|
||
---
|
||
|
||
## 6. 明确不做(本方案非目标)
|
||
|
||
1. 重写前端框架 / 换 React
|
||
2. 删减 58→15 的硬删除(只做分层与转发)
|
||
3. 改 Board/NATS/dispatch 协议
|
||
4. 改 new-api / auto-pi 路由
|
||
5. 强制 16 神兽全部 rebuild(除非模板变更)
|
||
6. 生产防火墙、跨 VM 批量高危 prlctl
|
||
7. 把 joy web 变成真派活引擎(dispatch 仍是真源)
|
||
|
||
---
|
||
|
||
## 7. 推荐执行顺序与工期
|
||
|
||
| 顺序 | Phase | 工期 | 风险 | 可独立合并 |
|
||
|------|-------|------|------|------------|
|
||
| 1 | Phase 0 基线 | 0.5d | 低 | ✅ |
|
||
| 2 | Phase 1 发现层 | 0.5–1d | 低 | ✅ |
|
||
| 3 | Phase 2 schema_version | 1d | 低 | ✅ |
|
||
| 4 | Phase 3 dashboard 拆分 | 1–2d | 中 | ✅ 需 L5 验 web |
|
||
| 5 | Phase 4 deprecated 转发 | 0.5–1d | 中 | ✅ |
|
||
| 6 | Phase 5 web audit | 1–2d | 中 | ✅ |
|
||
| 7 | Phase 6 懒加载/清理 | 1d | 低–中 | ✅ |
|
||
| 8 | Phase 7 门禁固化 | 1d | 低 | 与上并行 |
|
||
|
||
**合计约 6–10 人日**。建议 **每 Phase 单独 commit**,每 Phase 跑 §7.2 检查单再进下一 Phase。
|
||
|
||
---
|
||
|
||
## 8. 与既有文档关系
|
||
|
||
| 文档 | 关系 |
|
||
|------|------|
|
||
| `docs/joy-panel-cli-architecture-plan.md` | 产品 IA / 核心 15 愿景;**本方案是其「兼容优先落地版」** |
|
||
| `linuxjoy/docs/specs/2026-07-07-joy-python-rewrite.md` | Python 重写已完成;本方案是 2.0 后硬化 |
|
||
| `linuxjoy/docs/tools/joy-cli-reference.md` | 需在 Phase 4/7 同步(可滞后代码一个 commit) |
|
||
| `office/*/AGENTS.md` + `joy-clones.sh` | **消费者**;改模板仅当 ABI 真变 |
|
||
|
||
---
|
||
|
||
## 9. 决策请求(执行前需菲比斯确认)
|
||
|
||
| # | 问题 | 建议默认 |
|
||
|---|------|----------|
|
||
| D1 | 是否按 Phase 0→7 全做? | **是**,按序 |
|
||
| D2 | schema 附加字段用 `_joy.schema_version` 还是顶层 `schema_version`? | **`_joy` 命名空间** 更安全 |
|
||
| D3 | `work_rebuild` 是否增加 `work rebuild` sub 并保留旧入口? | **是** |
|
||
| D4 | 本阶段是否允许「仅文档」把 konqi 的 `prlctl` 写法改成 `vm`? | 是,但代码转发必须先在 |
|
||
| D5 | web execute 是否强制二次确认(已有则加强)? | **是** |
|
||
| D6 | 是否在本方案中处理未提交 hardware tab? | **分开 PR**,不与硬化混提 |
|
||
|
||
---
|
||
|
||
## 10. 一句话总结
|
||
|
||
**在不打断 joy web 常驻、三员 AGENTS、神兽 CLAUDE 的前提下,把 joy-cli 从「58 命令功能堆」收成「可版本化、可测试、可转发废弃」的长期 ABI;先契约与拆分,后加固与清理;每一刀都用 golden + 消费者检查单验收。**
|
||
|
||
---
|
||
|
||
## 11. 修订
|
||
|
||
| 日期 | 变更 |
|
||
|------|------|
|
||
| 2026-07-10 | 首版完整方案:调用面审计 + 影响矩阵 + Phase 0–7 + 测试门禁 |
|
||
|
||
|
||
## 12. 执行记录
|
||
|
||
| 日期 | 内容 |
|
||
|------|------|
|
||
| 2026-07-10 | Phase 0–7 落地:golden fixtures、tier/help 同源、`_joy.schema_version`、dashboard 包拆分、deprecated 转发、web JSONL audit、懒加载、contract 测试;pytest 54 绿;launchd web/dashboard 回归 |
|