Commit Graph
438 Commits
Author SHA1 Message Date
openqj e5bf361c6d Merge pull request #149 from openqj/feat-no-full-confirm
console: 新建任务选完全访问不再弹确认框
2026-10-29 18:17:16 +08:00
host 6d9cd24553 console: 新建任务选完全访问不再弹确认框
DispatchSection 提交时删掉 full 的 window.confirm:下拉里
选 full 本身就是显式选择,提交直接送 approval,不再二次
确认。计划模式与 full 互斥的拦截不动,其它确认框(取消/
合并/提 PR 等)不动。
构建产物 cloud/console.html 由 npm run build(tsc + vite
singlefile)重新生成,产物里已无“确认提交吗”,仅剩下拉
选项本身的“完全访问”文案。
2026-10-29 18:06:18 +08:00
openqj baf330f112 Merge pull request #148 from openqj/feat-console-goal-invincible
console: 增加 goal 模式无敌版勾选
2026-10-29 18:05:19 +08:00
host 7d400afa37 console: add goal-mode invincible option
DispatchSection gains a 'goal 模式无敌版' checkbox next to 'goal 模式':
checking it sends goal_mode=1 plus no_time_limit=1 (server already
accepts the field; the console just never exposed it). Plain goal
checkbox behavior is unchanged; invincible wins when both are
checked. Plan/coordinator mutual exclusion now covers invincible
too (it is a goal variant). TaskDetailPanel shows
'goal 模式无敌版(不限时)' when a task carries no_time_limit.
Help text states the honest boundary: worker/docker total timeouts
are lifted, the 600s single-turn host guard stays. Built with
npm run build (tsc+vite pass); console.html synced verbatim from
dist/index.html.
2026-10-29 17:58:50 +08:00
openqj 9961a251d1 Merge pull request #147 from openqj/feat-prestart-goal-logs
worker: 补漏:goal 路径的 docker 分段日志 + 审计任务 id
2026-10-29 17:52:30 +08:00
host 6f0eec71b6 worker: cover goal docker paths with prestart stage logging
PR #145 added docker_run_* lines only to _run_in_container, but
goal/goal-resume/goal-resume-breakpoint call _call_runner directly
(to keep full stdout for goal conclusions), so the production live
test (a goal task) produced zero docker_run_ lines. Extract a
_docker_call_staged helper and route all four task paths through it;
error lines log the class name then re-raise so each caller's
kill+failed handling is unchanged.

Also fix audit attribution: audit_log has no task_id column, and
worker_exec_done/error details carried no task id, so per-task
queries missed them (the rows existed). All three exec details now
start with task_id=. Tests: 2 new goal-path stage cases + a done
detail task-id assertion (8 total in test_prestart_stages).
2026-10-29 17:46:12 +08:00
openqj a17f0c7412 Merge pull request #145 from openqj/feat-prestart-logs
worker: 启动前分段日志(派发卡死可定位)
2026-10-29 17:33:05 +08:00
host 9d90d97046 worker: prestart stage logging for dispatch stalls
Claim-to-dispatch stalls (cf. 2026-10-29 task A: 61s to interrupted
with zero detail) were invisible because docker run blocks with
captured output and watchdog kills were silent. Add three layers:
- worker_exec_start/done/error audit rows in _run_attempt (PG,
  survives --rm), start/done pairing shows whether an attempt died
  inside the executor call;
- docker_run_start/done/error log lines in DockerExecutor (container
  + image only, never the inner command/prompt);
- stdout tail (last 2000 chars) to the worker log on failed or
  interrupted results, and a log line on both watchdog kill paths.
Tests: cloud/tests/test_prestart_stages.py, 6 cases incl. a
no-prompt-in-logs assertion.
2026-10-29 17:07:53 +08:00
openqj 0129b0149a Merge pull request #144 from openqj/feat-neverstart-fresh
worker: 从未启动的任务自动续跑回落全新跑
2026-10-29 16:51:42 +08:00
host e74f20608b worker: auto-resume falls back to fresh goal for never-started tasks
2026-10-29 live test: task A was interrupted 61s after claim but had
never written anything (no host-state entry, no worktree, no trace,
no checkpoint); auto-resume ran goal-resume, which host rightly
refused, and the task failed. Refusal only makes sense for tasks
with progress but a lost breakpoint (those go through the P0
checkpoint rebuild); for a never-started task the only meaningful
outcome is a fresh run, identical to its first attempt (same task
id, same goal, worktree does not exist yet so nothing is
overwritten).

Change (claim path only, via _resolve_breakpoint_resume):
- rebuild from checkpoint first, unchanged;
- if rebuild fails AND _task_never_started holds (state entry,
  checkpoint row, worktree dir, trace file all absent), clear the
  breakpoint flag so the run takes the fresh goal path, with a
  worker_fresh_restart audit event;
- any evidence of prior execution, or any check failure,
  keeps the old refusal path (fail-closed); the auto-resume
  count cap and no-progress stall guard still bound retries.

Tests: cloud/tests/test_neverstart_fresh.py, 10 items (fallback
holds, entry/checkpoint/worktree/trace presence each block it,
corrupt state blocks it, rebuild still wins when a checkpoint
exists); test_goal_resume's breakpoint-routing test now sets up
a task with a checkpoint so it still exercises goal-resume.
Full suites: cloud 1178 (skipped 4), host 104, deploy 39, green.
2026-10-29 16:45:07 +08:00
openqj a4586cbebc Merge pull request #143 from openqj/feat-harness2-followups
harness2: per-role models, sweep batch, task file assets endpoint
2026-10-29 16:39:48 +08:00
host c20192bce8 harness2: per-role models, sweep batch, task file assets endpoint
- Role models: run_improvement_via_tasks gains role_models
  (probe/editor/selector/reflector) plus --model-<role> CLI flags;
  missing/empty falls back to shared --model, both empty means
  server default, so default behavior is unchanged.
- Sweep: run_sweep + examples/harness2_sweep.py manifest CLI with
  shared library_root (library restore), per-run failure isolation
  and sweep-report.json summary; preflight gates task creation.
- Deliverable assets: GET /tasks/{id}/files for local-executor
  tasks (safe path resolution, UTF-8 text <=256KB, listing <=200;
  docker/cloud/cross-host 409 with explicit reason, since tenant
  Docker shares one /app/work per project and per-task attribution
  would misattribute); probe rollout deliverable_files from the
  endpoint plus DELIVERABLE FILE reply blocks (endpoint wins on
  collision, bad blocks dropped), surfaced in
  deliverables/<label>/files/ context and full_result summary.
- Docs: harness2.md comparison table updated for all three items.
2026-10-29 16:32:58 +08:00
openqj 9e444eca38 Merge pull request #142 from openqj/feat-state-lock
host: 修复断点丢失(tmp 碰撞 + 跨容器 flock 失效)
2026-10-29 16:04:12 +08:00
host 9ea0a05fb1 host: fix state-loss from tmp collision and cross-container flock failure
2026-10-29 task 2 lost its host-state entry (version 390 -> single
digits) while running under Docker/gVisor. Root cause, proven live:
- save_state tmp name contained only pid, and every containerized
  host.py runs as pid 1, so concurrent writers shared one tmp file
  and interleaved writes produced corrupt JSON;
- fcntl.flock does not exclude across runsc containers sharing a
  bind-mounted lock file (both entered at 0.0s in a live probe);
- _read_state_file silently treated corrupt JSON as empty state, so
  the next save legitimately rewrote the file with only the
  surviving writer's tasks.

Fix:
- tmp name now hostname + pid + thread + uuid4 (backup tmp same);
- mkdir atomic lock replaces flock (atomic on the host fs, holds
  across bind mounts/gofer), with stale-lock recovery after 120s
  and a loud timeout instead of unlocked writes; reads need no lock
  because publication is tmp + os.replace;
- save path uses a strict disk read: corrupt JSON, non-object top
  level, or wrong-shaped tasks/automations now raise instead of
  overwriting (recovery stays with restore_state + .bak).

Tests: tests/test_host_state_lock.py, 7 items (tmp uniqueness in
process and across processes, 8-process concurrent saves all
survive with version 8, stale lock recovery, fresh lock timeout
raises, corrupt/wrong-shaped disk refuses to overwrite).
Full suites: cloud 1168 (skipped 4), host 104, deploy 39, all green.
2026-10-29 15:57:46 +08:00
openqj 7425f2e778 Merge pull request #141 from openqj/feat-harness2-gaps
harness2: upstream gap fill — trivial fix, session budget, tag validation, preflight
2026-10-29 15:40:09 +08:00
openqj 4d16d63313 Merge pull request #140 from openqj/feat-longtask-p0-three
断点镜像状态标签回落:host-state 条目写 status 不是 goal_status
2026-10-29 15:37:51 +08:00
host 4ed1479d7a harness2: upstream gap fill — trivial selection fix, session budget, run_tag validation, preflight check
- select_final trivial condition now k==1 and single-candidate pool,
  regardless of whether a selector is provided (previously gated on
  selector is None, so wired runs always paid for a useless selector
  task at k=1)
- Budget gains max_sessions gate (probe + stage-attempt sessions;
  fmt2 corrections and selector/reflector sessions exempt), the
  backstop for unpriced models where the USD gate never binds
- validate_run_tag (charset, no leading '-', no s<N> seed prefix)
  enforced at run_improvement_via_tasks and the CLI
- CLI --check preflight (base harness, source dir, prompt, tag,
  control-plane /health probe) without creating tasks
- ModeResult.to_dict now includes rollout summaries so a lost probe
  is visible in full_result instead of only on the server
- CLI plan counts the selector only when k>1
2026-10-29 15:31:58 +08:00
host 8c719c7e62 断点镜像状态标签回落:host-state 条目写 status 不是 goal_status
生产实弹:极小 goal 任务的 timeline 里 checkpoint goal_status 为
None——host.py 的任务条目只有 status(goal-running/goal-met),
没有 goal_status 键,镜像原样读 goal_status 永远是空。修法:
entry.get('goal_status') or entry.get('status')。轮次、thread_id、
state_sha 等关键字段不受影响(熔断只看轮次),纯标签 fidelity
修复;单测加 status-only 条目镜像断言。
2026-10-29 15:31:07 +08:00
openqj 3d60f32bd3 Merge pull request #139 from openqj/feat-longtask-p0-three
长任务 P0 三件:断点进库、错误分类+熔断、Run/Step 时间线
2026-10-29 15:19:43 +08:00
host 585242fc8f 长任务 P0 三件:断点进库、错误分类+熔断、Run/Step 时间线
断点进库:task_checkpoints 表(PG 新库 + 老库幂等补表 + 迁移清单
对齐);worker 在 goal 任务执行期间每 30 秒把磁盘 host-state 断点
镜像进库,终局再补一次;断点续跑认领前,若 host-state 条目丢失
但库里有断点,先按库断点重建最小条目再跑,库里也没有断点时不
造假、走原有拒绝路径。

错误分类+熔断:sandbox 四处解析加永久错误分支(KeyError、配置
缺失等无结论异常退出判 failed 死信,不再判 interrupted;host 已
明言 interrupted 的不受影响,未知错误不分类);worker 自动恢复
加退避(10 秒起指数退避、封顶 300 秒)与无进展熔断(库断点轮次
连续 3 次不变即标 auto_resume_stalled 等人工)。

时间线:task_steps 表 + host 每轮写 host-steps 步骤文件 + worker
导入;GET /tasks/{id}/timeline 一次返回 steps 与 checkpoints;
认领、暂停、自动恢复、终局都记步骤。旧任务返回空数组,不编造。

单测:cloud/tests/test_p0_three.py 14 项(分类、熔断、镜像重建、
步骤导入去重、timeline 接口)。
2026-10-29 15:13:01 +08:00
openqj d56bd3a99e Merge pull request #138 from openqj/feat-harness2
harness2: recursive harness optimization wired to real codex tasks
2026-10-29 14:28:44 +08:00
openqj b34812f605 Merge pull request #137 from openqj/feat-longtask-resume-guard
fix: 断点丢失时 goal-resume 拒绝成 failed,阻断自动恢复空转
2026-10-29 14:24:44 +08:00
host 42abe3cc5b harness2: recursive harness optimization wired to real codex tasks
Port Google Research's Harness^2 method layer (model weights frozen,
only the surrounding harness is optimized): Propose-Probe-Compose with
INV/DOM/AGG editors, parallel/sequential modes, per-domain experience
library, anonymous-product selection, k<=3 hard cap and budget gate.
Execution goes only through the existing control-plane API (upload ->
task with idempotency key -> poll -> trace/cost -> cancel on timeout);
no new server endpoints, no codex flags composed, tasks inherit the
normal executor/sandbox/quota/audit path.

Wiring lessons from four real rounds against production (project
wwww, ledger task): HttpTaskClient retries transient disconnects and
502/503/429 (3 attempts); editors get a worked file-block example, an
explicit <no-change> marker and one feedback retry (.fmt2) instead of
silently accepting notes-only replies; run_task unwraps the server's
result_text JSON envelope (text field holds the real reply) — without
this, line-anchored file-block parsing could never see blocks the
agents were actually emitting. Final round (real4) fully green:
all stages landed, selection non-fallback, experience入库, probe
delivers the correct signed total 85.15.

Tests: 35 harness tests (17 method + 18 wiring incl. fake-control-plane
full round, idempotent replay, retry, format retry, envelope round).
Deliberate deviations from upstream are documented in docs/harness2.md
(no network-unrestricted/sandbox-disabled defaults, auto_apply off,
no benchmark/scorer, probe deliverable = final reply text).
2026-10-29 14:21:18 +08:00
host a5f2e4e091 fix: 断点丢失时 goal-resume 拒绝成 failed,阻断自动恢复空转
2026-10-29 长任务实弹:Docker goal 断点续跑在 host-state 里找
不到任务时抛 KeyError,worker 把无结论异常退出判 interrupted,
自动恢复再排队、再 KeyError,12 秒一轮空转 49 次(人工暂停
拦下,第 50 次人工续跑又烧掉),文件 32 章原样未动。
修法:host.py goal-resume 先查任务在不在 state 里,不在就打印
拒绝行、正常退出;sandbox 三处解析(本地、Docker resume、
Docker 断点)见拒绝行即判 failed 终态,不进自动恢复循环。
单测:host 缺任务拒绝不炸 + 三处解析拒绝判 failed。
2026-10-29 14:14:13 +08:00
openqj e48b756f96 Merge pull request #136 from openqj/feat-longtask-invincible
无敌补齐:连续失败上限 + worker退出审计 + 配额恢复自动续跑
2026-10-29 13:16:49 +08:00
host ae3aff8602 feat: 长任务无敌补齐三件:连续失败上限 + worker退出审计 + 配额恢复自动续跑
1. host goal 循环连续失败护栏:3 轮连续失败即中断出口,
   任务记 interrupted、可断点续跑,不再无限空转
   (2026-10-29 实弹:断点后 274 轮全失败)。
2. worker 退出杀残留路径补审计 worker_shutdown_interrupted,
   detail 为任务 id,与 sweep_interrupted 同口径。
3. 配额中断自动恢复:每轮现查配额,仍超限/查不到时留
   在 interrupted 不重排队,下轮再查;现查为 None 时
   (新月份/额度上调/无价上限重置)才 CAS 回 queued。

单测:配额仍超限不动、配额恢复续跑、连续 3 轮失败停转。
2026-10-29 13:07:57 +08:00
openqj 88fcfeebd3 Merge pull request #135 from openqj/feat-console-keys-ui
CI verify pass. Deploy follows separately via deploy.py.
2026-10-29 12:57:18 +08:00
host a68b63e0f1 console: API Key 区补生成/列表/撤销(调现有自助接口) 2026-10-29 12:51:00 +08:00
openqj 49f3ff7cb6 Merge pull request #134 from openqj/feat-longtask-docker-resume-env
修法:Docker 断点续跑透传密钥环境(SUB2API_API_KEY 缺失空转)
2026-10-29 12:48:12 +08:00
host 5b2bdc9bbf fix: Docker 断点续跑透传密钥环境(SUB2API_API_KEY 缺失空转修法)
Docker goal_resume_breakpoint_task 是唯一漏传
env=self._docker_cli_env(extra_env) 的 goal 方法:密钥只按名
进 docker run,值靠 CLI 环境带;漏传导致容器内 key 为空,
断点后每轮瞬间报 Missing SUB2API_API_KEY、无限空转
(2026-10-29 长任务实弹:274 轮全失败)。

单测:断言断点方法调用 runner 时 CLI 环境含密钥值,
命令里密钥只按名出现不带值。
2026-10-29 12:42:19 +08:00
openqj c757810097 Merge pull request #133 from openqj/feat-longtask-auto-resume
长任务中断自动恢复:仅用户暂停才暂停,不限时
2026-10-29 11:48:22 +08:00
host c9cfe22a36 feat: 长任务中断自动恢复,仅用户暂停才暂停,不限时
- 新增 tasks 列 paused_by_user/interrupted_reason/auto_resume_count/no_time_limit(幂等迁移,server+worker 双侧)
- POST /tasks/{id}/pause:用户暂停标 interrupted + paused_by_user=1;/cancel 同款标记;人工 /retry、/goal-resume 清标记
- sweep 标 sweep、配额标 quota、协调员孤儿标 coordinator_orphan、worker 退出标 worker_shutdown
- worker.run_loop 每轮后 auto_resume_interrupted:只接系统中断的 goal 任务,CAS 回 queued + goal_resume_pending=1(G10 断点续跑),用户暂停/配额/孤儿/非 goal 不接,上限 50 次防无限烧额度
- no_time_limit=1 的任务 worker/Docker 级不限时(其它任务仍默认 1800 秒;host 单轮 600 秒仍是单轮护栏)
- 前置 cherry-pick:G10 断点续跑透传 model_provider(否则 Docker 断点续跑在 sub2api 下必死,自动恢复无法实证;本 PR  supersedes #127,勿另行合并 #127)
2026-10-29 11:37:06 +08:00
host a19b1567bb fix: G10 断点续跑透传 model_provider(sub2api 续跑失败修法)
断点续跑容器不带 --model-provider 时 Server 的 provider 表里
没有 sub2api,thread/resume 报 provider not found(probe15 实弹)。
Docker/Local 断点方法加可选 model_provider 并转发,worker 两处
调用点传 gateway_provider;补单测断言断点命令含
--model-provider sub2api(旧代码下两新测试 1 失败 1 报错)。
2026-10-29 11:28:39 +08:00
openqj 0ef896c317 Merge pull request #132 from openqj/feat-console-gapfix
console: 分栏改独立容器,修模块间空白间距
2026-10-29 11:04:22 +08:00
host e5aa5c2acb console: 分栏改独立容器,修模块间空白间距
PR #130 的共享网格行是根因:一行高度由该行最高模块决定,
任务列表撑高第 2 行后,对话(第 3 行)只能从任务列表底下开始,
派发/环境等短模块下面空出一大截;align-items:start 只让盒子
不拉伸,拉不上来下一行。

修法:App.tsx 把模块包进三个独立 .dash-col(左:任务+项目,
中:派发+对话,右:环境+Workers+技能+自动化+分诊+管理区+
API Key),栏内 flex 纵向紧贴;中屏两栏(左+中上右下)、宽屏
三栏并排;窄屏用 display:contents + 每模块 order 恢复原单列
顺序。构建产物 316093 字节,sha 与构建输出一致。
2026-10-29 10:56:36 +08:00
openqj e7f7edf5c2 Merge pull request #131 from openqj/feat-readme-update
docs: README 对齐生产现状(main 93c25a9,补 PR #130 自适应分栏)
2026-10-29 10:48:52 +08:00
host b27d98e642 docs: README 基线跟进到 main 93c25a9,补 PR #130 自适应分栏 2026-10-29 10:43:01 +08:00
host da0c7d453e docs: README 对齐生产现状(main 4c3420a)
- 顶部新增项目现状:生产 Postgres + api.diante.me + React 命令台 GitHub 风格
- 新增云端控制面一节:状态机、worker/扩容、配额成本、记忆搜索、继续/计划/followup/fork、部署链路
- 纠正过期表述:云端不再是演示、PR/CI 本仓已走通(旧无远端/无登录已过期)、多机同步走中心库
- 新增诚实边界:内层 bwrap、40 人暂搁置、单机 HA 模拟、PR #127 未合并
2026-10-29 10:42:27 +08:00
openqj 93c25a92bc Merge pull request #130 from openqj/feat-console-adaptive
console: 按宽度自适应分栏(一栏/两栏/三栏)
2026-10-29 10:35:54 +08:00
host c89c157e5d console: 按宽度自适应分栏(一栏/两栏/三栏)
GitHub 风格不变,仅 tokens.css 改布局:窄屏 <900px 一栏
(按原 DOM 顺序堆叠),中屏 900–1399px 两栏(左:任务列表
+ 项目,右:派发 + 对话 + 详情 + 环境 + Workers + 技能 +
自动化 + 分诊 + 管理区 + API Key),宽屏 >=1400px 三栏
(左 310px:任务列表 + 项目,中弹性:派发 + 对话 + 详情,
右 330px:环境 + Workers + 技能 + 自动化 + 分诊 + 管理区
+ API Key),盒子按内容高度不拉伸,页面最大宽 1560px,
窄屏断点修正为 899px 避免与 900px 重叠。console 标记单测
本地 53 项通过。
2026-10-29 10:30:16 +08:00
openqj 4c3420ae8e Merge pull request #129 from openqj/feat-console-github
console: GitHub 风格(Primer)
2026-10-29 10:21:44 +08:00
host e90c885290 console: GitHub 风格(Primer)
保持一页式控制台排版与全部功能、API 不变,只换视觉:
深色顶栏 #24292f、Primer 浅色配色(边框 #d0d7de、链接蓝
#0969da、绿主按钮 #2da44e)、6px 圆角方框、系统字体与
等宽 ID/trace;任务列表改 issues 式(状态圆点 + 标题 +
灰色元信息);对话改评论时间线(白框 + 头部 + 正文,
竖线连接),灰/蓝气泡已移除;自动选项目与继续消息历史
不受影响。console 标记单测本地 53 项通过。
2026-10-29 10:13:30 +08:00
openqj bbe02efc14 Merge pull request #128 from openqj/feat-console-dashboard
console: 一页式控制台排版 + 数据卡片
2026-10-29 10:04:17 +08:00
host 8b455c6554 console: 一页式控制台排版 + 数据卡片
保持 Muse 风格(白底、细线、灰/浅蓝气泡),不再四栏切视图:
顶栏(连接/健康/配额/刷新 + 锚点导航)+ 6 张数据卡片
(健康、配额、任务、Workers、项目、项目数据,均取自已有
store 数据,未加载不以 0 充数)+ 所有模块按顺序铺在一页
(派发、任务列表、对话+详情、项目、环境、Workers、技能、
自动化、分诊、管理区、API Key)。图标栏与右侧栏删除,
内容分别移到顶栏与各自模块下;今天列表与任务列表重复,
不再单独保留;对话为空时不再重复渲染派发表单。
含自动选第一个项目修复(主要聊天不再空)与继续消息
历史,console 标记单测本地 53 项通过。
2026-10-29 09:57:26 +08:00
openqj a13762cfbe Merge pull request #126 from openqj/feat-chat-history
chat: 持久化继续消息,chat-history 交替历史
2026-10-29 07:07:34 +08:00
host f02c513729 chat: 持久化继续消息,chat-history 交替历史
基线 main 811912c(PR #125 Muse 风格之后):服务端与单测与
9538825 相同;React 侧在 Muse 风格 ContinuePanel 上重放
chat-history 集成(新版输入框占位文案保持 Muse 风格的“消息”),
console.html 由新版 src 重新构建。

- 新表 task_continue_messages:POST /continue 的用户消息与状态改回
  queued 同一事务落盘,409 被拒不留 phantom 消息
- GET /tasks/{id}/chat-history:prompt + 继续 + 后续消息 + 链路按
  时间交错拼好返回;部署前继续以 legacy_continue_count 如实标注
- React ContinuePanel 优先用 chat-history,旧服务端自动回退
2026-10-29 07:01:57 +08:00
openqj 811912c841 Merge pull request #125 from openqj/feat-console-muse-style
console: 按 Muse 网页端/桌面端视觉重做
2026-10-29 06:58:11 +08:00
host 66790b5123 console: 按 Muse 网页端/桌面端视觉重做
仅视觉与布局改动,功能与 API 未改:全屏四栏(56px 图标栏 +
260px 列表 + 弹性对话 + 300px 右侧栏),左侧搜索 + 主要聊天
列表,中间灰/浅蓝气泡对话 + 圆角输入条,右侧头像 + 已连接
(真实 key/健康状态)+ 今天任务清单,下方仍可展开原详情。
旧 v3 松绿/朱印与顶部大标题栏已移除,产物为单文件
(316226 字节,sha f8fea987…,本地重建字节一致)。
console 标记单测未动,本地 53 项通过。
2026-10-29 06:52:34 +08:00
openqj 5ca5cc91cc Merge pull request #124 from openqj/feat-console-react
console: React 生产级重写(左列表 + 中对话 + 右详情)
2026-10-29 06:38:35 +08:00
host ebc5624893 console: React 生产级重写(左列表 + 中对话 + 右详情)
旧单页 console.html 换成 Vite + React + TypeScript 单文件构建产物
(309525 字节,sha 90345ec8…,重建字节一致),源码在
cloud/console-react/,改页面只改 src 再 npm run build:console,
产物不手改。布局:左侧列表(模块导航 + 任务列表)、中间标准对话
(实时链路时间线 + 继续会话聊天框,共用 Chat 组件)、右侧详情
(元数据、操作、评审、审批、协调子任务、子代理、线程)。
API 与后端语义未改,key 只存浏览器 localStorage。
6 个 console 标记单测随实现改名更新(意图不变:壳确实调了
这些接口、turn 信息仍在详情里、旧 goal 输入仍不存在);
P1 标记单测未动且通过。
2026-10-29 06:32:38 +08:00