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 COMMAND [OPTIONS]

Commands:
  run        Run the OCLoop orchestration loop
  bootstrap  Create a starter PLAN.md and .loop-prompt.md in a directory

ocloop run

ocloop run [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

ocloop bootstrap

ocloop bootstrap [DIRECTORY] [OPTIONS]

Arguments:
  DIRECTORY          Directory to initialise  [default: current directory]

Options:
  -f, --force        Overwrite existing files
  --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>

Bootstrap and run:

# Create starter files in a new directory
ocloop bootstrap ./myproject

# Edit the generated files, then run from inside the directory
# (--plan defaults to PLAN.md and --prompt defaults to .loop-prompt.md)
cd myproject
ocloop run --model openai/gpt-4.5 --run

Or run from outside the directory by specifying paths explicitly:

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

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.2.0.tar.gz (82.2 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.2.0-py3-none-any.whl (17.3 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for pyocloop-0.2.0.tar.gz
Algorithm Hash digest
SHA256 335820cee54a1745f7abd64ed704325f09bd104afbfee90334c994b940558725
MD5 27e8874348171b0a2879d36521095d9b
BLAKE2b-256 2870b37b3215ce0b4c8a790dde12d3a80447e6bece25c8210dd31c3d086af8b9

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyocloop-0.2.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.2.0-py3-none-any.whl.

File metadata

  • Download URL: pyocloop-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 17.3 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.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3c5a3dc80fc27c2aa7a71e9c0296b419782c53e948193a47cea53d890247600d
MD5 ffe708748ee5c33b3e4004e85035495a
BLAKE2b-256 5b49ce983872f4a75f10f69cd3c629b9e2570ff64681cac070ecdab134eeed86

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyocloop-0.2.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