pyocloop
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
- pyocloop starts an
opencode servesubprocess - 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
- OpenCode reads the plan, executes the next task, marks it
[x], and optionally appends<plan-complete>when done - The TUI shows live progress: task counter, progress bar, current task, token count, and elapsed/average time per iteration
- The loop stops when OpenCode writes
<plan-complete>to the plan file
Requirements
- Python 3.11+
- OpenCode installed and configured (
opencodeon 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
anthropicprovider 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
Metadata
Release files for pyocloop 0.3.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| pyocloop-0.3.1.tar.gz | 87.6 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pyocloop-0.3.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 105.1 kB
Release files / pyocloop-0.3.1.tar.gz
| Download URL | pyocloop-0.3.1.tar.gz |
|---|---|
| Size | 87.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7e1989cddc1bcf54eda9ec0c690f56f69f37606ac9b136437f3f3c01e6eb00ca
|
|
BLAKE2b-256 checksum How to use checksums |
0a57465c833e01f46626eec5fd6e80a0b44c8e2e8ee8010f12ce059d5042bc1e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 2, 2026.
Transparency logRelease files / pyocloop-0.3.1-py3-none-any.whl
| Download URL | pyocloop-0.3.1-py3-none-any.whl |
|---|---|
| Size | 17.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f8e5b706706b0c87c2b095e49eb0df3947e3e9abfc95c55205a5cbfc85c44dd6
|
|
BLAKE2b-256 checksum How to use checksums |
276f7cd7bfd3bf5d30b561688439daf3022b2efa49bceacafbdab6957e3cf853
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 2, 2026.
Transparency logSecurity for pyocloop 0.3.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for pyocloop-0.3.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 2, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.