Skip to main content

TUI loop harness that orchestrates OpenCode to execute tasks from a PLAN.md file iteratively

Project description

pyocloop

pyocloop screenshot

A Python TUI that orchestrates OpenCode to execute tasks from a PLAN.md file iteratively, one session at a time.

pyocloop is inspired by and compatible with ocloop by @d3vr. It reimplements the same concept in pure Python using Textual, fixing TUI display issues and a path resolution bug present in the original.

How it works

  1. pyocloop starts an opencode serve subprocess
  2. On each iteration it creates a session, sends your loop prompt (with the plan file path injected), and waits for the session to go idle
  3. OpenCode reads the plan, executes the next task, marks it [x], and optionally appends <plan-complete> when done
  4. The TUI shows live progress: task counter, progress bar, current task, token count, and elapsed/average time per iteration
  5. The loop stops when OpenCode writes <plan-complete> to the plan file

Requirements

  • Python 3.11+
  • OpenCode installed and configured (opencode on your PATH)

Installation

git clone https://github.com/rbarzic/pyocloop
cd pyocloop
pip install .

For development (editable install):

pip install -e .

Usage

ocloop [OPTIONS]

Options:
  -m, --model TEXT   Model to use (format: providerID/modelID).
                     List available models with: opencode models
  -a, --agent TEXT   Agent to use
  --prompt PATH      Path to loop prompt file  [default: .loop-prompt.md]
  --plan PATH        Path to plan file         [default: PLAN.md]
  -p, --port INT     OpenCode server port      [default: 4096]
  -r, --run          Start iterations immediately (no keypress needed)
  -d, --debug        Debug mode (skip plan file validation)
  --verbose          Log every SSE event in the activity panel
  --log PATH         Write all log entries to a file
  --help             Show this message and exit

Key bindings

Key Action
S Start the loop
Space Pause / Resume
R Retry after an error
Q Quit (aborts current session)

Example

The examples/ directory contains a self-contained demo: answering EU capitals quiz questions.

File layout:

your-project/
├── PLAN.md              # task list (or use --plan to point elsewhere)
├── .loop-prompt.md      # instructions for OpenCode (or use --prompt)
└── ...

examples/PLAN.md — task list:

# EU Capitals Quiz Plan

## Backlog

### Phase 1: Western Europe

- [ ] **1** What is the capital of Austria?
- [ ] **2** What is the capital of Belgium?
- [ ] **3** What is the capital of France?
...

examples/loop-prompt.md — loop prompt (note the {{PLAN_FILE}} placeholder):

Execute the next task from {{PLAN_FILE}}.

Before starting:
1. Read {{PLAN_FILE}} fully

Task selection:
- Pick the FIRST uncompleted task
- Mark it [x] after completion

Completion check:
- If all tasks are [x] or [BLOCKED], append:
  <plan-complete>SUMMARY</plan-complete>

Run:

cd examples/
ocloop \
  --model openai/gpt-4.5 \
  --prompt ./loop-prompt.md \
  --plan ./PLAN.md \
  --run

Or with relative paths from any directory:

ocloop \
  --model openai/gpt-4.5 \
  --prompt /path/to/loop-prompt.md \
  --plan /path/to/PLAN.md

Plan file format

- [ ] Pending task
- [x] Completed task
- [MANUAL] Task requiring human intervention (skipped by the loop)
- [BLOCKED: reason] Task that could not be completed

The loop ends when OpenCode appends this tag to the plan file:

<plan-complete>Summary of what was done</plan-complete>

Loop prompt tips

  • Use {{PLAN_FILE}} as the placeholder — pyocloop replaces it with the absolute path at runtime
  • Instruct OpenCode to mark tasks [x] after completion and append <plan-complete> when all done
  • Keep prompts focused: one task per session works best for reliable progress tracking

Available models

Run opencode models [provider] to list models for a specific provider. Below are the models available at time of writing (your installation may differ):

Provider --model value Notes
OpenAI openai/gpt-5.5 Latest flagship
OpenAI openai/gpt-5.5-pro Pro tier
OpenAI openai/gpt-5.5-fast Faster/cheaper
OpenAI openai/gpt-5.4-mini Lightweight
z.ai (coding) zai-coding-plan/glm-5.1 Coding-optimised
z.ai (coding) zai-coding-plan/glm-5-turbo Fast coding model
z.ai (coding) zai-coding-plan/glm-4.7 Previous gen
z.ai (limited ctx) zai-limited-context/glm-5.1 Smaller context window
DeepSeek opencode/deepseek-v4-flash-free Free via opencode
GitLab Duo gitlab/duo-chat-sonnet-4-6 Anthropic Sonnet via GitLab
GitLab Duo gitlab/duo-chat-opus-4-7 Anthropic Opus via GitLab
GitLab Duo gitlab/duo-chat-gpt-5-4 GPT-5.4 via GitLab

Anthropic models can be used directly if you configure the anthropic provider in opencode.

Architecture

pyocloop does not call any LLM directly. It delegates all AI work to the opencode binary:

ocloop (Textual TUI)
  └─ opencode serve  (subprocess)
       ├─ POST /session          create session
       ├─ POST /session/{id}/prompt_async  send prompt
       ├─ GET  /event?directory=…          SSE stream (progress events)
       └─ GET  /config                     detect active model

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyocloop-0.1.0.tar.gz (81.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyocloop-0.1.0-py3-none-any.whl (16.1 kB view details)

Uploaded Python 3

File details

Details for the file pyocloop-0.1.0.tar.gz.

File metadata

  • Download URL: pyocloop-0.1.0.tar.gz
  • Upload date:
  • Size: 81.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pyocloop-0.1.0.tar.gz
Algorithm Hash digest
SHA256 664beec8b50cbbe4fbd168a1c3dcd8f8a4397d76f380699afc9bab57d5c1dc41
MD5 2f7458752a641a1494e3783f178874d3
BLAKE2b-256 fd1dbe8a34092c7b718c419133966e0005d3ce3589c10242929ca35da318f09a

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyocloop-0.1.0.tar.gz:

Publisher: publish.yml on rbarzic/pyocloop

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyocloop-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: pyocloop-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 16.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pyocloop-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5d75cfbeba28f34767adb7d947f7d38cd5e3c210505c94ce730f481befd29477
MD5 4c14712f59160f9f121caf8dafbdc6fb
BLAKE2b-256 a4e4f5cf0edac272ef0b7a4961c06addbf5755326233d4c12365820f9e09c8c3

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyocloop-0.1.0-py3-none-any.whl:

Publisher: publish.yml on rbarzic/pyocloop

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page