Skip to Content
Dev富排版组件 demo

富排版组件 demo

P2 阶段的所有自定义组件 + diagram plugin + Matrix 语义类的可视化样品页。 仅用于开发期肉眼对照现有 HTML 截图;不进 sidebar (content/_meta.ts 不列)。

Badge

普通: draft 2026-05-22

强调: accent ok

状态: warning danger info

带 dot: draft passed

Card · CardGrid

需求 A

任务类型可扩展

OpenSpec 4 阶段是当前唯一形态。但 spec-kit / TDD 循环 / bug fix from issue 都是合理 task type 候选。

需求 B

用户运行中追加指令

30 min 任务中段, 用户想干预: “这里加个测试” / “跳过这步” / “换个方向”。

需求 C

主 API 重启不丢事件流

每次 deploy → in-process streamLogs loop 死 → 任务被 janitor 60min 后误判 failed。

G1 · 产品需求

双向通道

web ↔ 主 API ↔ sandbox-agent 三段全部走 WebSocket, 用户能在任务运行中追加指令。

sunk 样式 (无阴影, bg-sunk)

用于次要的、需要视觉降级的卡片。e.g. 不再活跃的 spike 总结。

Decision

D1通信形态 = WebSocket 双向 (替代 SSE + stdout JSONL)

决定: web ↔ 主 API ↔ sandbox-agent 三段全部走 WebSocket, 由中间的 sandbank Relay 桥接。

理由:

  • G1 (用户追加指令) 需要 client → server 双向, SSE 做不到
  • Claude Agent SDK 原生支持 query({ prompt: AsyncIterable<SDKUserMessage> })
  • Fly.io 官方: “WebSocket implementation is very straightforward; no third-party tools necessary”

代价:

  • web 端 EventSource 改 socket.io-client (一次性迁移)
  • run.js 改为 streamInput + AsyncIterable 模式

Phase

P1

WebSocket 双向链路接入1 周

  • 建立 sandbank Relay fly app
  • 主 API 加 @WebSocketGateway
  • web 端 EventSource → socket.io-client
P2

任务类型插件化2 周

  • task-spec.json 协议定稿
  • RunnerRegistry 表上线
  • openspec / spec-kit / tdd-cycle 三个 plugin 适配 HostContext ABI
P3

多 task 并发隔离3-5 天

  • Relay channel = task_id 验证
  • ResubscribeBootstrap 接入主 API 启动钩子

Matrix (markdown 表格 + cell 语义类)

场景当前行为影响
主 API deploystreamLogs loop 断每次 deploy 期间 running 的 task 失去事件流
web 标签页切走SSE 自动重连✓ 不丢
用户中途追加指令无通路只能 destroy 整个 sandbox 重新派发
用户想接受 permission容器内 bypassPermissionsN/A (设计上跳过)

KVList

web ↔ 主 API
@Sse
主 API ↔ sandbox
handle.streamLogs()
web 自动重连
浏览器 EventSource 内建 (3s retry + Last-Event-ID)
主 API ↔ sandbox 重连
不存在 — in-memory loop 死即断

Diagram (fenced code block ```diagram, remark-diagram plugin 转换)

┌──────────────────────────────────────────────────────────────────────────┐ │ web (browser) 主 API (NestJS, Fly) sandbox │ │ │ │ │ │ │ │ EventSource (SSE) │ │ │ │ │ ◄────── 单向 ─────────────│ │ │ │ │ │ │ │ │ │ │ adapter.streamLogs() │ │ │ │ │ ReadableStream<Uint8> │ │ │ │ │ ◄──── 单向 ───────────────│ │ │ │ │ (sandbox stdout JSONL) │ │ └──────────────────────────────────────────────────────────────────────────┘ • web→主 API: HTTP POST /tasks/:id/dispatch (一次性,非通道) • 主 API→sandbox: 仅在 dispatch 时 provider.create(env, …) 注入,之后无通路 legend: tag (绿色加粗) · dim (灰色) · new (蓝色加粗) · drop (红色线穿)