anomalyco / anomalyco/opencode

[FEATURE]: add wait built-in tool with countdown in footer

Open
#50,041 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
209k
Forks
27.5k
PR merge metrics
PR metrics pending

Description

[FEATURE]: add wait built-in tool with countdown in footer

Summary

Add a Core built-in wait tool that blocks for N seconds while publishing
Tool.Progress updates, and render a countdown in the TUI footer instead of
the generic spinner.

Why

Claude Code has a WAIT tool that blocks (in tool-call queue, async to the
agent loop) and shows countdown in footer — useful for:

  • CI / deployment wait loops (wait N seconds then check status)
  • Avoiding busy-poll bash: sleep 1; check
  • First real consumer of the Tool.Progress event (currently defined but unused)

We already have all the infrastructure:

  • Tool.Progress event schema (packages/schema/src/session-event.ts:331-340)
  • TUI footer spinner (packages/tui/src/component/prompt/index.tsx:1515-1594)
  • App reducer already handles session.tool.progress (packages/app/src/context/server-session-v2-reducer.ts:276)
  • Tool.make + permission.assert pattern (see webfetch.ts)
  • Effect.gen for time-based orchestration
  • Async tool execution via FiberSet.run (packages/core/src/session/runner/llm.ts:278) — wait runs in parallel with sibling tool calls in the same turn, like all other tools

Proposed contract

Input:  { seconds: 1..600, reason?: string }
Output: { waited: number, reason?: string }

Hard cap 600s to discourage wait(seconds=86400) (Claude Code removed wait
after abuse — same model here).

Implementation sketch

  1. packages/core/src/tool/wait.ts — new built-in
    • Effect.gen with 1Hz ticker publishing Tool.Progress with { remainingSeconds, totalSeconds, reason } in structured/metadata
    • permission.assert({ action: "wait", resources: [] }) — every call requires approval unless allowlisted (same as webfetch)
    • Built-in registered in packages/core/src/tool/builtins.ts + new location node
  2. packages/tui/src/component/prompt/index.tsx — match progress.structured.type === "wait"⠋ 12s remaining (reason); fallback to generic spinner for non-wait tools
  3. packages/app/src/...RunningToolPart (or wherever running tool is rendered) reads metadata; if structured.type === "wait" show 12s remaining. App reducer already passes metadata through (packages/app/src/context/server-session-v2-reducer.ts:282).
  4. Tests: extend packages/core/test/session-tool-progress.test.ts with wait-specific cases (cap enforcement, permission gating, progress event cadence)

Out of scope (future)

  • Stage 3: URL polling source (wait({ url, expect: 2xx }))
  • Stage 4: pluggable sources via opencode.tools.register

Open questions (to resolve during impl)

  1. How exactly to publish Tool.Progress from inside Tool.make execute — the publisher lives in runner/publish-llm-event.ts; need to verify the channel exposed to tool leaves. May need a new lightweight ctx.progress.emit(structured) accessor.
  2. Permission resource for wait (webfetch uses URL; wait has no resource — []?).
  3. Footer vs timeline rendering trade-off (TUI has both — pick one or both).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read the existing Tool.Progress schema in packages/schema/src/session-event.ts, the webfetch Tool.make and permission.assert pattern, and the footer rendering in packages/tui/src/component/prompt/index.tsx. Trace progress handling through packages/app/src/context/server-session-v2-reducer.ts and tool execution in packages/core/src/session/runner/llm.ts. Done means the wait tool, registration, rendering, permission behavior, and cases in packages/core/test/session-tool-progress.test.ts are defined and tested.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
cli, developer-experience, frontend
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.