Skip to content

feat: support Claude Code as a host with a read-only task waiter - #49

Open
Han7872 wants to merge 1 commit into
Sandyzzx:masterfrom
Han7872:claude/claude-code-host-v1.2.7
Open

Han7872 wants to merge 1 commit into
Sandyzzx:masterfrom
Han7872:claude/claude-code-host-v1.2.7

Conversation

@Han7872

@Han7872 Han7872 commented Oct 30, 2026

Copy link
Copy Markdown
Collaborator

Summary

Claude Code can connect to the Bridge through MCP, but the skill assumes a Codex host and long waits require repeated calls to zcode_events with its 25-second limit. This adds a read-only waiter that Claude Code can run in the background and host-specific guidance for resuming when attention is needed.

  • Add scripts/wait-task.mjs to the plugin, using only Node built-ins. It reads task status and event logs, exits for a pending interaction, a terminal status, or a deadline, and never writes Bridge state.
  • Make the skill host-neutral, document Claude Code background waiting and the absence of Goal support, and retain the existing Codex Goal rules.
  • Add ADR-010, interface documentation, waiter regression tests, and plugin validation for the packaged waiter and its imports.

MCP tool names, schemas, task state semantics, and runtime dependencies remain unchanged. The waiter provides observations only; interaction decisions and task acceptance still go through the existing host workflow. This does not add or claim a tested Claude Code plugin installation manifest.

Validation

Independently run on macOS with Node.js v26.5.0 against commit 13ab83626a7fa7f35319a21244215c2915ecb112:

  • npm run typecheck — passed
  • npm run build:test — passed
  • TMPDIR=/private/tmp node --test dist-test/test/wait-task.test.js dist-test/test/validate-plugin-root-pattern.test.js — 23 passed, 0 failed
  • npm run build — passed; tracked bundles remain unchanged
  • npm run validate:plugin — passed
  • git diff --check — passed; clean working tree after validation

The focused test run initially had one validator-fixture failure under the macOS /tmp alias; using the canonical /private/tmp temporary directory resolved it without source changes. Full npm test, a live Claude Code/ZCode end-to-end run, and cross-platform/version certification were not rerun for this PR submission.

Claude Code has no Goal tool and is notified when a background command
exits, so polling zcode_events in 25-second slices costs a host tool call
per slice. Add plugins/codex-zcode-bridge/scripts/wait-task.mjs: a
dependency-free reader of status.json/events.jsonl/events.gen that exits
on an unanswered interaction, a terminal status, or a deadline, and never
writes Bridge state (observation only, ADR-004/ADR-010).

Make the skill host-neutral with a Claude Code section, document the
waiter in INTERFACES.md and ADR-010, and have validate:plugin require the
waiter and reject non-builtin imports. MCP tools, schemas and task state
semantics are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AND5VcsL1v2kDgRUmQGjtQ

@Sandyzzx Sandyzzx left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

独立审查:三个 P2 建议修复后合并

先说做得好的:合同纪律(零 MCP schema/状态语义/依赖变更)、只读边界("不写文件"有快照测试钉住)、validate:plugin 的 node: 内置白名单,这些方向都对。我在 base 0e74ee1c(master)上独立核实了等待器的结构假设:存储布局与 src/store/task-store.ts 一致;数据根解析(config → env → ~/.codex/codex-zcode-bridge)与 src/host/stdio.ts 的插件模式回退逐行一致;快乐路径的交互配对、退出码、游标语义在本机冒烟(Windows, Node 24.16.0, head 13ab836)全部通过。

但以下三个问题在源码路径上成立,并已由确定性合成探针复现,请求修改:

P2-1 失效交互优先于终态,且未按当前 attempt 过滤(必修)

位置:plugins/codex-zcode-bridge/scripts/wait-task.mjs 的 pending 生命周期(waitForTask 主循环)。

等待审批期间 attempt 因 timeout/abort 结束时,并不保证产生 SETTLED 集合内的事件:

  • src/worker/run-task.ts(master, 审批等待循环超时分支)只返回 decline("The task attempt ended before the calling host replied"),不落任何 settle 事件;
  • src/adapters/zcode-app-server-adapter.ts 在 abort 时于发出 interaction_replied 之前提前 return;
  • src/manager/task-manager.ts 的 replyToInteraction 只接受 running 状态,非 running 一律 TASK_STATE。

探针复现:

  1. status=failed(attempt 1, 未答审批, 无 settle 事件)→ 输出 reason=interaction, status=failed。宿主被唤醒去回复一个 manager 必然拒绝的请求,且 interaction 优先于 terminal 让假唤醒持续存在。
  2. status=running, attempt=2,attempt 1 的请求无 settle → 仍报 attempt 1 的 pending。

期望:attempt 边界清除失效 pending;终态优先于失效 interaction,报告 terminal 让宿主走终态处理。

P2-2 对所有事件统一剥离数字前缀,原生 request ID 无法配对(随 P2-1 一并修)

worker 在原生 ID 前加 <attempt>:(仅 interaction_requested 等发布侧事件),而 interaction_replied 携带未加前缀的原生 ID;adapter 接受任意非空字符串 requestId,不禁止 数字: 形态。统一 replace(/^\d+:/u, "") 后:

  • requested 1:7:perm → 配对键 7:perm;
  • replied 原生 7:perm → 配对键 perm,永不匹配。

探针确认:请求已 replied,仍返回 reason=interaction。建议只对 requested 侧剥离恰好一层 <attempt>: 前缀,replied 侧保留原值比较;结合 P2-1 一并做 attempt 感知配对。

P2-3 跨轮询的 UTF-8 多字节字符永久损坏(必修)

EventTail.read 每次读取独立 .toString("utf8"),partial 保存的是已解码字符串。追加边界切在多字节字符中间时,两次解码各自产生 U+FFFD,拼接后不可恢复。探针把 1:审批 的事件行在"审"的首字节后切开、间隔追加余下字节,得到 pending.request_id = "1:\uFFFD\uFFFD批";中文问题与审批输入同样会损坏。

仓库内同布局的 TaskStore.readEvents 用的正是 StringDecoder。建议 partial 保存未解码 Buffer(或改用 StringDecoder),并在代际重置时一并重置。现有"半行"测试只在 ASCII 区域切分,建议补多字节切分用例。


非阻塞备注

  • INTERFACES/ADR 把 waiting_for_master 归入"任务终态";它在 Bridge 语义里可续作。该措辞与 P2-1 的 interaction 优先级相互放大,建议改为"终态或等待宿主"。
  • ADR 头部建议沿用仓库现有四行格式(Status / Last updated / Last verified / Verified against),日期与实际提交对齐。
  • validate:plugin 的 import 白名单是正则启发式(createRequire + require() 可绕过)——纵深防御备注,不阻塞。

验证边界

  • 已核实:三个 P2 由 master 源码路径 + 本机确定性探针复现(head 13ab836, Windows, Node 24.16.0);数据根复刻、无写入保证、快乐路径配对、合同不变式独立核实通过;CI 双平台绿。
  • 未运行:本机完整 npm test(以 CI 为准)、真实 Claude Code 后台通知 E2E——不据此作兼容认证。三个边界均未声称在真实 Claude Code/ZCode 会话中观察到。

@Sandyzzx

Sandyzzx commented Nov 1, 2026

Copy link
Copy Markdown
Owner

感谢 PR #49 的贡献。我们认可 Claude Code 后台等待器的功能方向。

目前 Bridge 正在准备 SQLite 正式生产接入。由于此次变更可能影响 Task Status、Attempt 和 Interaction 的权威数据来源,我们计划先完成 SQLite 切换,再提供一项通用的只读 Task Attention State 能力。

该能力将统一判断任务终态和当前 Attempt 的有效待处理交互,供 Claude Code 及其他 Host 复用,从而避免在 Waiter 中重复实现事件 tail、Request ID 配对和状态管理逻辑。

因此建议暂缓本 PR 的大规模修改,保持开放状态。SQLite 切换及相关状态合同确认后,我们再确定最小适配方案。

现有三个 P2 审查问题仍然有效,合并前需要解决,并完成实际 Claude Code Host E2E 验证。

这属于项目集成顺序调整,并不否定 PR 的功能价值。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants