Files
cc-web/.planning/2026-08-26-standard-javascript-session/task_plan.md

3.7 KiB
Raw Blame History

标准 JavaScript 会话编排实施计划

Goal

为 cc-web 增加受控的 JavaScript 脚本编排能力:通过 MCP 创建、写入、异步启动和停止脚本,并注入 @ccweb/session 标准包,让脚本 Promise 化调用现有 ccweb 会话。

Current Phase

Phase 5交付收尾

Phases

Phase 1需求与代码链路确认

  • 汇总已确认的 API、脚本生命周期、异常通知和错误协议
  • 使用 codebase-memory 确认现有 MCP、会话创建、消息发送和 steer 入口
  • Status: complete

Phase 2MCP 契约与脚本运行基础

  • 新增脚本 MCP 工具定义和 API manifest验收tools/list 能发现 create/write/run/get_run/stop/api 工具,工具输入 schema 和 manifest 可 JSON 序列化
  • 新增脚本目录、ESM 标准包注入和路径校验;验收:只能访问当前 cwd/.ccweb/scripts 下的 .js包可被裸名 import
  • 新增异步脚本运行注册表、日志落盘、停止和重启恢复验收runId 查询、stdout/stderr 分段读取、stop 吊销凭据、重启标记 killed
  • Status: complete

Phase 3会话标准包与服务端编排

  • 实现 Promise 化的当前会话、创建、发送、最后消息和语义分支能力;验收:每个 API 返回约定字符串/ID错误携带稳定 code/details
  • 接入现有 ccweb 会话状态、Codex App steer 和异常来源会话通知;验收:同对话复用 steer不重复运行同脚本异常才插入来源通知
  • Status: complete

Phase 4测试与回归

  • 编写脚本 MCP、标准包和异常通知回归测试
  • 运行语法检查、单元回归和项目 regression
  • 修复发现的问题并记录验证结果
  • Status: complete

Phase 5交付

  • 清理临时 TODO CSV 和本计划状态
  • 汇总变更、测试结果、风险和未覆盖边界
  • Status: complete

Key Questions

  1. 如何在不让脚本轮询的情况下等待现有会话完成?——由服务端等待会话状态和持久化消息变化。
  2. 如何让同对话消息复用现有 steer且不重复启动同一脚本——调用现有 handleMessage/steer并按来源+脚本路径拒绝并发重复运行。
  3. 如何在脚本异常结束时通知来源对话,同时区分主动 stop——运行注册表记录 stopRequested只有非主动失败插入通知。

Decisions Made

Decision Rationale
独立 Node 子进程运行脚本 隔离脚本异常并支持异步执行
.js + type=module,注入 @ccweb/session 保持用户示例并支持显式 ESM import/顶层 await
服务端实现 Promise 等待 脚本不实现监听、轮询和等待封装
同对话发送复用现有 steer/插入 避免并行 turn 和递归死锁
运行记录和 stdout/stderr 持久化 支持异步 runId 查询、重启标记和长输出分段读取
主动 stop 不插入来源对话 MCP 成功/失败结果已经是调用反馈
非正常结束插入来源对话通知 让启动脚本的 Agent 感知异常并继续处理

Errors Encountered

Error Attempt Resolution
用户级 planning-with-files 技能路径不存在 1 改用项目内 .codex/skills/planning-with-files/ 版本

Notes

  • 不覆盖根目录已有的旧 task_plan.mdfindings.mdprogress.md,本任务使用 scoped planning 目录。
  • 按已确认需求不设置运行时长、输出和并发硬上限;完整日志落盘,单次 get_run 只返回尾部或显式范围,避免无限响应。
  • 脚本按受信代码执行,不伪造 JavaScript 沙箱仍限制脚本路径、MCP 凭据生命周期和运行记录归属。