codexloop 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- codexloop/__init__.py +3 -0
- codexloop/application/__init__.py +1 -0
- codexloop/application/dto.py +41 -0
- codexloop/application/ports.py +158 -0
- codexloop/application/runner.py +467 -0
- codexloop/application/usecases/__init__.py +1 -0
- codexloop/application/usecases/doctor.py +37 -0
- codexloop/application/usecases/list_threads.py +14 -0
- codexloop/application/usecases/preflight.py +10 -0
- codexloop/application/usecases/resume_thread.py +11 -0
- codexloop/application/usecases/run_control.py +20 -0
- codexloop/application/usecases/run_plan.py +11 -0
- codexloop/bootstrap.py +461 -0
- codexloop/cli/__init__.py +1 -0
- codexloop/cli/app.py +94 -0
- codexloop/cli/asyncio.py +80 -0
- codexloop/cli/commands/__init__.py +1 -0
- codexloop/cli/commands/approval_cmd.py +24 -0
- codexloop/cli/commands/capacity.py +33 -0
- codexloop/cli/commands/cwd_cmd.py +22 -0
- codexloop/cli/commands/doctor.py +27 -0
- codexloop/cli/commands/effort_cmd.py +24 -0
- codexloop/cli/commands/logs.py +15 -0
- codexloop/cli/commands/model_cmd.py +22 -0
- codexloop/cli/commands/prompt.py +32 -0
- codexloop/cli/commands/reset.py +25 -0
- codexloop/cli/commands/resume.py +38 -0
- codexloop/cli/commands/run.py +50 -0
- codexloop/cli/commands/runs.py +13 -0
- codexloop/cli/commands/sandbox_cmd.py +24 -0
- codexloop/cli/commands/savepoints.py +25 -0
- codexloop/cli/commands/snapshot.py +26 -0
- codexloop/cli/commands/status.py +15 -0
- codexloop/cli/commands/stop.py +21 -0
- codexloop/cli/commands/threads.py +15 -0
- codexloop/cli/commands/unwind.py +24 -0
- codexloop/cli/commands/watch.py +66 -0
- codexloop/cli/render.py +39 -0
- codexloop/domain/__init__.py +26 -0
- codexloop/domain/approval.py +38 -0
- codexloop/domain/backoff.py +34 -0
- codexloop/domain/budget.py +56 -0
- codexloop/domain/capacity.py +81 -0
- codexloop/domain/classify.py +98 -0
- codexloop/domain/completion.py +130 -0
- codexloop/domain/control.py +167 -0
- codexloop/domain/error_codes.py +75 -0
- codexloop/domain/errors.py +35 -0
- codexloop/domain/loop.py +190 -0
- codexloop/domain/model_profile.py +30 -0
- codexloop/domain/plan.py +38 -0
- codexloop/domain/savepoint.py +32 -0
- codexloop/domain/savepoint_message.py +56 -0
- codexloop/domain/session.py +32 -0
- codexloop/domain/signals.py +25 -0
- codexloop/domain/waiting.py +120 -0
- codexloop/infrastructure/__init__.py +0 -0
- codexloop/infrastructure/agent/__init__.py +0 -0
- codexloop/infrastructure/agent/argv.py +102 -0
- codexloop/infrastructure/agent/events.py +274 -0
- codexloop/infrastructure/agent/gateway.py +189 -0
- codexloop/infrastructure/agent/probe.py +74 -0
- codexloop/infrastructure/agent/process.py +208 -0
- codexloop/infrastructure/agent/schema.py +31 -0
- codexloop/infrastructure/agent/scripted.py +201 -0
- codexloop/infrastructure/agent/translate.py +120 -0
- codexloop/infrastructure/api/__init__.py +26 -0
- codexloop/infrastructure/api/api_baseline.json +340 -0
- codexloop/infrastructure/api/binder.py +170 -0
- codexloop/infrastructure/api/gateway.py +142 -0
- codexloop/infrastructure/api/introspect.py +248 -0
- codexloop/infrastructure/api/json_io.py +26 -0
- codexloop/infrastructure/api/params.py +162 -0
- codexloop/infrastructure/api/providers.py +70 -0
- codexloop/infrastructure/api/registry.py +13 -0
- codexloop/infrastructure/appserver/__init__.py +6 -0
- codexloop/infrastructure/appserver/client.py +245 -0
- codexloop/infrastructure/appserver/gateway.py +437 -0
- codexloop/infrastructure/appserver/ratelimits.py +100 -0
- codexloop/infrastructure/audit.py +26 -0
- codexloop/infrastructure/capacity_probe.py +57 -0
- codexloop/infrastructure/clock.py +26 -0
- codexloop/infrastructure/config.py +150 -0
- codexloop/infrastructure/control.py +89 -0
- codexloop/infrastructure/doctor_env.py +239 -0
- codexloop/infrastructure/events.py +23 -0
- codexloop/infrastructure/git_savepoints.py +176 -0
- codexloop/infrastructure/lock.py +88 -0
- codexloop/infrastructure/logging.py +124 -0
- codexloop/infrastructure/notify.py +27 -0
- codexloop/infrastructure/progress.py +14 -0
- codexloop/infrastructure/redact.py +52 -0
- codexloop/infrastructure/rollout.py +113 -0
- codexloop/infrastructure/rundir.py +57 -0
- codexloop/infrastructure/snapshot.py +39 -0
- codexloop/infrastructure/state.py +32 -0
- codexloop/infrastructure/state_bus.py +27 -0
- codexloop/infrastructure/stream_ui.py +44 -0
- codexloop/py.typed +0 -0
- codexloop-0.1.0.dist-info/METADATA +104 -0
- codexloop-0.1.0.dist-info/RECORD +104 -0
- codexloop-0.1.0.dist-info/WHEEL +4 -0
- codexloop-0.1.0.dist-info/entry_points.txt +2 -0
- codexloop-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""Workspace snapshot helper — copy tree excluding ``.codexloop/``."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import shutil
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
_SKIP = {".codexloop", ".git"}
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def create_snapshot(*, cwd: Path, dest: Path) -> Path:
|
|
12
|
+
"""Copy ``cwd`` into ``dest``, skipping control-plane and ``.git`` dirs."""
|
|
13
|
+
dest.mkdir(parents=True, exist_ok=True)
|
|
14
|
+
for child in cwd.iterdir():
|
|
15
|
+
if child.name in _SKIP:
|
|
16
|
+
continue
|
|
17
|
+
target = dest / child.name
|
|
18
|
+
if child.is_dir():
|
|
19
|
+
shutil.copytree(child, target, dirs_exist_ok=True)
|
|
20
|
+
elif child.is_file(): # pragma: no branch
|
|
21
|
+
shutil.copy2(child, target)
|
|
22
|
+
return dest
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def restore_snapshot(*, snapshot: Path, cwd: Path) -> None:
|
|
26
|
+
"""Restore files from ``snapshot`` into ``cwd`` (does not delete extras)."""
|
|
27
|
+
if not snapshot.is_dir():
|
|
28
|
+
raise FileNotFoundError(f"snapshot not found: {snapshot}")
|
|
29
|
+
for child in snapshot.iterdir():
|
|
30
|
+
target = cwd / child.name
|
|
31
|
+
if child.is_dir():
|
|
32
|
+
if target.exists(): # pragma: no branch
|
|
33
|
+
shutil.rmtree(target)
|
|
34
|
+
shutil.copytree(child, target)
|
|
35
|
+
elif child.is_file(): # pragma: no branch
|
|
36
|
+
shutil.copy2(child, target)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
__all__ = ["create_snapshot", "restore_snapshot"]
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""RunStateStore — persist run state as ``state.json`` under a run directory."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from collections.abc import Mapping
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
from codexloop.infrastructure.redact import redact
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class FileRunStateStore:
|
|
13
|
+
def __init__(self, runs_root: Path) -> None:
|
|
14
|
+
self._runs_root = runs_root
|
|
15
|
+
|
|
16
|
+
def _path(self, run_id: str) -> Path:
|
|
17
|
+
return self._runs_root / run_id / "state.json"
|
|
18
|
+
|
|
19
|
+
def load(self, run_id: str) -> dict[str, object] | None:
|
|
20
|
+
path = self._path(run_id)
|
|
21
|
+
if not path.is_file():
|
|
22
|
+
return None
|
|
23
|
+
data = json.loads(path.read_text(encoding="utf-8"))
|
|
24
|
+
if not isinstance(data, dict):
|
|
25
|
+
return None
|
|
26
|
+
return data
|
|
27
|
+
|
|
28
|
+
def save(self, run_id: str, state: Mapping[str, object]) -> None:
|
|
29
|
+
path = self._path(run_id)
|
|
30
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
31
|
+
safe = redact(dict(state))
|
|
32
|
+
path.write_text(json.dumps(safe, default=str) + "\n", encoding="utf-8")
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Minimal run-state bus: read ``state.json`` for ``watch`` / status helpers."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def read_state(path: Path) -> dict[str, object]:
|
|
10
|
+
"""Return parsed state.json, or ``{}`` if missing/invalid. Never raises."""
|
|
11
|
+
try:
|
|
12
|
+
if not path.is_file():
|
|
13
|
+
return {}
|
|
14
|
+
data = json.loads(path.read_text(encoding="utf-8"))
|
|
15
|
+
if isinstance(data, dict):
|
|
16
|
+
return data
|
|
17
|
+
except (OSError, json.JSONDecodeError):
|
|
18
|
+
return {}
|
|
19
|
+
return {}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def watch_state(path: Path) -> dict[str, object]:
|
|
23
|
+
"""Alias for :func:`read_state` — one-shot snapshot for ``watch``."""
|
|
24
|
+
return read_state(path)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
__all__ = ["read_state", "watch_state"]
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""Optional Textual live token view (``--stream-ui``).
|
|
2
|
+
|
|
3
|
+
!!! note "Roadmap"
|
|
4
|
+
Full token streaming against a live app-server session is still experimental.
|
|
5
|
+
This module ships a minimal Textual shell that tails a JSONL event file so
|
|
6
|
+
``watch --replay`` and ``--stream-ui`` have a working path today.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
from textual.app import App, ComposeResult
|
|
14
|
+
from textual.widgets import Footer, Header, RichLog
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class StreamUiApp(App[None]):
|
|
18
|
+
"""Tail a JSONL event log in a Textual window."""
|
|
19
|
+
|
|
20
|
+
CSS = """
|
|
21
|
+
RichLog { height: 1fr; }
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def __init__(self, path: Path) -> None:
|
|
25
|
+
super().__init__()
|
|
26
|
+
self._path = path
|
|
27
|
+
|
|
28
|
+
def compose(self) -> ComposeResult:
|
|
29
|
+
yield Header()
|
|
30
|
+
yield RichLog(id="log", highlight=True, markup=False)
|
|
31
|
+
yield Footer()
|
|
32
|
+
|
|
33
|
+
def on_mount(self) -> None:
|
|
34
|
+
log = self.query_one("#log", RichLog)
|
|
35
|
+
if not self._path.is_file():
|
|
36
|
+
log.write(f"(no events yet at {self._path})")
|
|
37
|
+
return
|
|
38
|
+
for line in self._path.read_text(encoding="utf-8").splitlines():
|
|
39
|
+
log.write(line)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def run_stream_ui(path: Path) -> None: # pragma: no cover — interactive TUI entry
|
|
43
|
+
"""Blocking entry used by the CLI ``--stream-ui`` flag."""
|
|
44
|
+
StreamUiApp(path).run()
|
codexloop/py.typed
ADDED
|
File without changes
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: codexloop
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Onion-architected, autonomous OpenAI Codex session runner — never blocks on a human, distinguishes rate limits from exhausted credits, and resumes safely across usage windows.
|
|
5
|
+
Project-URL: Homepage, https://github.com/adammatthewsteinberger/codexloop
|
|
6
|
+
Project-URL: Repository, https://github.com/adammatthewsteinberger/codexloop
|
|
7
|
+
Project-URL: Documentation, https://adammatthewsteinberger.github.io/codexloop/
|
|
8
|
+
Project-URL: Issues, https://github.com/adammatthewsteinberger/codexloop/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/adammatthewsteinberger/codexloop/blob/main/CHANGELOG.md
|
|
10
|
+
Author-email: Adam Matthew Steinberger <adam@matthewsteinberger.com>
|
|
11
|
+
License-Expression: MIT
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: agent,automation,cli,codex,gpt,llm,openai
|
|
14
|
+
Classifier: Development Status :: 3 - Alpha
|
|
15
|
+
Classifier: Environment :: Console
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
18
|
+
Classifier: Operating System :: MacOS
|
|
19
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
20
|
+
Classifier: Programming Language :: Python :: 3
|
|
21
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
25
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
26
|
+
Classifier: Topic :: Utilities
|
|
27
|
+
Classifier: Typing :: Typed
|
|
28
|
+
Requires-Python: >=3.12
|
|
29
|
+
Requires-Dist: anyio>=4.0
|
|
30
|
+
Requires-Dist: openai>=1.40
|
|
31
|
+
Requires-Dist: structlog>=24.1
|
|
32
|
+
Requires-Dist: textual>=1.0
|
|
33
|
+
Requires-Dist: typer>=0.12
|
|
34
|
+
Provides-Extra: dev
|
|
35
|
+
Requires-Dist: bandit>=1.7; extra == 'dev'
|
|
36
|
+
Requires-Dist: build>=1.2; extra == 'dev'
|
|
37
|
+
Requires-Dist: hypothesis>=6.100; extra == 'dev'
|
|
38
|
+
Requires-Dist: import-linter>=2.0; extra == 'dev'
|
|
39
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
40
|
+
Requires-Dist: packaging>=24.0; extra == 'dev'
|
|
41
|
+
Requires-Dist: pip-audit>=2.7; extra == 'dev'
|
|
42
|
+
Requires-Dist: pre-commit>=3.7; extra == 'dev'
|
|
43
|
+
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
|
|
44
|
+
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
45
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
46
|
+
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
47
|
+
Requires-Dist: twine>=5.0; extra == 'dev'
|
|
48
|
+
Provides-Extra: docs
|
|
49
|
+
Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
|
|
50
|
+
Description-Content-Type: text/markdown
|
|
51
|
+
|
|
52
|
+
# codexloop
|
|
53
|
+
|
|
54
|
+
Autonomous OpenAI Codex / GPT session runner. Same job as
|
|
55
|
+
[claudeloop](https://github.com/adammatthewsteinberger/claudeloop): never block on
|
|
56
|
+
a human, and never treat `insufficient_quota` / billing as a waitable
|
|
57
|
+
`rate_limit_exceeded` window.
|
|
58
|
+
|
|
59
|
+
**Status:** M1–M5 implemented on `feat/m1-pure-core` (onion core, exec gateway,
|
|
60
|
+
capacity probes, control plane, generated REST CLI, optional app-server transport
|
|
61
|
+
with exec fallback). MIT-licensed; author Adam Matthew Steinberger.
|
|
62
|
+
|
|
63
|
+
## Install
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
pip install -e ".[dev]"
|
|
67
|
+
codexloop --version
|
|
68
|
+
codexloop doctor
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Quick start
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
codexloop run path/to/plan.md
|
|
75
|
+
codexloop watch --follow
|
|
76
|
+
codexloop stop
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Plans
|
|
80
|
+
|
|
81
|
+
| Document | Purpose |
|
|
82
|
+
|---|---|
|
|
83
|
+
| [docs/plans/architecture-and-roadmap.md](docs/plans/architecture-and-roadmap.md) | Full design / transplant plan from claudeloop 0.5.4 |
|
|
84
|
+
| [docs/plans/research-notes.md](docs/plans/research-notes.md) | Vendor SDK/CLI capacity + autonomy research |
|
|
85
|
+
| [docs/plans/_shared-transplant-outline.md](docs/plans/_shared-transplant-outline.md) | Cross-product keep/swap + Global Constraints |
|
|
86
|
+
| [docs/superpowers/plans/2026-08-13-codexloop-implementation.md](docs/superpowers/plans/2026-08-13-codexloop-implementation.md) | Bite-sized TDD implementation plan |
|
|
87
|
+
|
|
88
|
+
## Naming
|
|
89
|
+
|
|
90
|
+
| Item | Value |
|
|
91
|
+
|---|---|
|
|
92
|
+
| PyPI / CLI | `codexloop` |
|
|
93
|
+
| Env prefix | `CODEXLOOP_*` |
|
|
94
|
+
| State dir | `.codexloop/` |
|
|
95
|
+
| Done marker | `CODEXLOOP_TASK_FULLY_COMPLETE` |
|
|
96
|
+
|
|
97
|
+
## License
|
|
98
|
+
|
|
99
|
+
MIT — see [LICENSE](LICENSE).
|
|
100
|
+
|
|
101
|
+
## Publishing
|
|
102
|
+
|
|
103
|
+
Releases go **TestPyPI → PyPI** via Trusted Publishing. See
|
|
104
|
+
[docs/publishing.md](docs/publishing.md).
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
codexloop/__init__.py,sha256=4pn6jbs-GOvSd4sYgcwzxYxP3zqNeSkuaevCFQaspJA,102
|
|
2
|
+
codexloop/bootstrap.py,sha256=bmNOlNS0Kd3an2O9Mgbua3Z5bFvc_8YKDN31UEAAmgE,15663
|
|
3
|
+
codexloop/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
codexloop/application/__init__.py,sha256=sA-g5WAYA6X6OjwNO78rPwgBkuevBxvDFTux5iW6kus,70
|
|
5
|
+
codexloop/application/dto.py,sha256=XCh-gBW0fj1iFxtIQZV-NKcNJyZNZ3lWCFOiYdrIRXo,1012
|
|
6
|
+
codexloop/application/ports.py,sha256=8cxdHtiQBKOuuNt_uuOuUe08Gg6nCisLq1luqSbuluY,4440
|
|
7
|
+
codexloop/application/runner.py,sha256=EJT90WlyOFJ6PWi3Tz5CC-PRiTHyXBoW6ssYxu623D0,17539
|
|
8
|
+
codexloop/application/usecases/__init__.py,sha256=h6nxf5zDeva7GLQERfXTFQhX1w8jEVRnC9KRWRa-i8A,77
|
|
9
|
+
codexloop/application/usecases/doctor.py,sha256=Gw-MV7EUpmBp-cQu28tdHfBalgR-7WIu5NoOfWxqegE,912
|
|
10
|
+
codexloop/application/usecases/list_threads.py,sha256=FUOSRq0V6OzxToFLIwZglfjYNkF-Fxxp0LbwfjqHcoc,395
|
|
11
|
+
codexloop/application/usecases/preflight.py,sha256=YXc-a0T62b7vBgxFSRnl4Zuv9ZBnmz_f5ChJYK7NbaU,296
|
|
12
|
+
codexloop/application/usecases/resume_thread.py,sha256=HFM6WFx5DdHrDXALQXb__8rK_Q2X1gvctU5OcnQjq58,424
|
|
13
|
+
codexloop/application/usecases/run_control.py,sha256=Pn4_22bPOriuFq-hH-vvhTU-kTp8tFTZse59Hbd_QaM,516
|
|
14
|
+
codexloop/application/usecases/run_plan.py,sha256=Ok0G9429gPP1oeCF27xjkbbx98paUmrmpi7ky0Dde24,422
|
|
15
|
+
codexloop/cli/__init__.py,sha256=xVwIR3leKTmk01M_WkyTgevbhQjGMovFd1Il7nPm2-I,61
|
|
16
|
+
codexloop/cli/app.py,sha256=WTiIR1fzodFXtFKNwjQo4B51gbHfwskSDOy0iAeimIk,2705
|
|
17
|
+
codexloop/cli/asyncio.py,sha256=vSjlel9dETZ85gBSuqsxf7tFZ-gLRsBFzsR3qk2LGRc,2222
|
|
18
|
+
codexloop/cli/render.py,sha256=XUxb56EQj2uM40BiwcGAdbFtTLYyS9UUf8076g9kqVA,1124
|
|
19
|
+
codexloop/cli/commands/__init__.py,sha256=E-c9v4cvPBJDhbLqd5B8fRpqM6ctCrLmy2FNIlISS7s,71
|
|
20
|
+
codexloop/cli/commands/approval_cmd.py,sha256=t7d5k_Bzw75_EtWLUb_kqJXwAiUodSBlAC8RWomyIAo,852
|
|
21
|
+
codexloop/cli/commands/capacity.py,sha256=ukFEJxNsCAbCwDIHVQvNqd5Kwq0r4ESzF5Na6F-nZkA,1147
|
|
22
|
+
codexloop/cli/commands/cwd_cmd.py,sha256=7coPWV-GQ64JIsGXSdf96K52Ws0nyV4IX_sL1UOoBOE,715
|
|
23
|
+
codexloop/cli/commands/doctor.py,sha256=zA8UVwwDVpxAIO5Tgn1rhHO0WdBZIiqjVUPxJWP3AP0,860
|
|
24
|
+
codexloop/cli/commands/effort_cmd.py,sha256=k9P43OOw4wneAzFmaQ9AQ8bm2TUw5apDZLqdV_LGb7s,819
|
|
25
|
+
codexloop/cli/commands/logs.py,sha256=nA8QwGT5K3gFFgpJNzx7TD-2eUEbYQELzmxBR3fYFBQ,386
|
|
26
|
+
codexloop/cli/commands/model_cmd.py,sha256=FBbLzGv1i9LA9hOEYxfuwdcWM18u2-kaP2nvTTjzZGQ,713
|
|
27
|
+
codexloop/cli/commands/prompt.py,sha256=h2QCjiD6u27lQ8rAPNhvuL1kr5qzXwKrJVllW3XfvEo,1195
|
|
28
|
+
codexloop/cli/commands/reset.py,sha256=uyN04Ql3ow7eQ4_abGHLBcrFZNw3Bji6wMFQ88NKtpM,928
|
|
29
|
+
codexloop/cli/commands/resume.py,sha256=8sOowNgyj5iLhBdGNrcSNKKkz1bjT86pFClOtMGNm3g,1371
|
|
30
|
+
codexloop/cli/commands/run.py,sha256=YvcKtXs_sSHx4TtlvR1CrJDe2cmzw6clWwm_rGceUiQ,1606
|
|
31
|
+
codexloop/cli/commands/runs.py,sha256=5-oG867i9W_KtQVhySwR3PClN-pZ-Bv0neWbVQaBFUo,296
|
|
32
|
+
codexloop/cli/commands/sandbox_cmd.py,sha256=CxkFVeCBWuzF0-eWpBU8BUHQq5VFKAF2Nu4ggT_5tiM,837
|
|
33
|
+
codexloop/cli/commands/savepoints.py,sha256=87DvgvxV_63bSrPb7Y8YK33k6CPLqP3FVO6nP55-IEc,793
|
|
34
|
+
codexloop/cli/commands/snapshot.py,sha256=xUxmoZH-NI1loobBLKJVdpTzGC6yMd6nlxfpzRj7YWY,1013
|
|
35
|
+
codexloop/cli/commands/status.py,sha256=K0NdYGAisqD6T9txuC_ClG4V75l406F3KfqEQjLxauo,396
|
|
36
|
+
codexloop/cli/commands/stop.py,sha256=3fzZF00no5aeMQ7XkJ2WRO11GpZZ7bxR0363hew7tIQ,651
|
|
37
|
+
codexloop/cli/commands/threads.py,sha256=xhkuUuBPpF8-FASKWe7knVHKaIB_KXTQVProWJnSQIY,483
|
|
38
|
+
codexloop/cli/commands/unwind.py,sha256=qIP_mwiwNbndgYjWxFjf3UJ7zguSUSxG9PDlGrOUSiY,925
|
|
39
|
+
codexloop/cli/commands/watch.py,sha256=YudvAnOnXXGB9tVX1wPf6Fo232cRdp7SPs4qnKSUX_I,1802
|
|
40
|
+
codexloop/domain/__init__.py,sha256=iUbe6xHDjX2VHmQ4MvA0so7ia5z_x4Cn2X4f52KAxgc,559
|
|
41
|
+
codexloop/domain/approval.py,sha256=_Ytz0NmlsLtZFzUOJv5S0oJwyDgEPTybS43qlJr9UdA,1024
|
|
42
|
+
codexloop/domain/backoff.py,sha256=Rpgig-85nHUUwzu0Dm90VvP-_M7ovJDwXVasFzTX9-I,1048
|
|
43
|
+
codexloop/domain/budget.py,sha256=UFe5bQM2ewsJCMONcX0GhJAALe_QOwYnQ0LXbpHlojw,1623
|
|
44
|
+
codexloop/domain/capacity.py,sha256=SgqpqTV-RxJohHzmvGxQB0wCy758xZ6BZ3MvYAV1gcQ,1938
|
|
45
|
+
codexloop/domain/classify.py,sha256=sTPS8AaWuP7jqi-zcegKpDCGclpZPcHp0sdwvx8YPU8,3517
|
|
46
|
+
codexloop/domain/completion.py,sha256=e3HuGLrhYdqdRp18oykWAOvikSTNxDyg5bqkQdxBeZw,3546
|
|
47
|
+
codexloop/domain/control.py,sha256=7sLWsCQ6hHsb1Sx_pGj2X2ayZv3usNyO0UfogegkyLk,4455
|
|
48
|
+
codexloop/domain/error_codes.py,sha256=JpzJzYf_P4sw3qIauz09bRmWHjItdxNr55qMlFxEu6I,1936
|
|
49
|
+
codexloop/domain/errors.py,sha256=fJ8c_MxVjHuftq3JTbcfrr2CWgn0fxVSHZHM-TtYC0A,867
|
|
50
|
+
codexloop/domain/loop.py,sha256=bZaDzUsDteG8aOBclNWufZKTRNtFeRjGIxLVteu0AWQ,5862
|
|
51
|
+
codexloop/domain/model_profile.py,sha256=DhEZ89eO19EfkymHjdkgLyDpety8QnWQHxUYoFQpfVg,715
|
|
52
|
+
codexloop/domain/plan.py,sha256=sf-nl5PMpvZK0ra9SatQALtxLER5T_UExulYgvPaOkQ,1101
|
|
53
|
+
codexloop/domain/savepoint.py,sha256=sOA1dg8JFMqwwZsLGZG7nrZxKFTmtknlPz0BJU2Xd-E,818
|
|
54
|
+
codexloop/domain/savepoint_message.py,sha256=lVKDE0l2D77TLKoxiHJeTvUCVAgEluqMTrplB0e7gMs,1711
|
|
55
|
+
codexloop/domain/session.py,sha256=8ns2wP3m79hqnLDNrQOPkgzAYsCjjwJbpICYqdW-P9A,542
|
|
56
|
+
codexloop/domain/signals.py,sha256=oEDyWQxpQ9pM9OX4S7hppE9b8T7Scee8Oeemy7E-TGY,745
|
|
57
|
+
codexloop/domain/waiting.py,sha256=hEJoYYMKZe7IuFZuV3oFXlUGX23jDQw4-JtweqloRPc,4353
|
|
58
|
+
codexloop/infrastructure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
59
|
+
codexloop/infrastructure/audit.py,sha256=TAYAQO911V8_2k_KazqYZGXiWOQf1MA98-mPi_ejKiY,821
|
|
60
|
+
codexloop/infrastructure/capacity_probe.py,sha256=j2-trejKb91Uy1LYSEf_zMhO8miJNRdbXTXCBiIVqFw,1754
|
|
61
|
+
codexloop/infrastructure/clock.py,sha256=sTpnsw1yJrfOrIl64iSisQFGOv9nMCIZhCAspQpMnzQ,723
|
|
62
|
+
codexloop/infrastructure/config.py,sha256=j2iPx0B3bntU49oc114aDm_V7orMlqB1nsKSKJIIvuI,4777
|
|
63
|
+
codexloop/infrastructure/control.py,sha256=7z2pLfvR2ADE6Zjv1ajm4YMVIee2PJIdBONCoWcaevs,3118
|
|
64
|
+
codexloop/infrastructure/doctor_env.py,sha256=096s30p9He9xo_BRM4ol5_Asjed7nopu8hyhdf4gS4M,8142
|
|
65
|
+
codexloop/infrastructure/events.py,sha256=Ap7JAgYcJmzMrlzjNwyOY0tuQAvee_X4otEggVTyPYE,697
|
|
66
|
+
codexloop/infrastructure/git_savepoints.py,sha256=G7hXjfQLeeyqIJGzauzxvb2w06H9wt9SYdPz1tS-uz0,6481
|
|
67
|
+
codexloop/infrastructure/lock.py,sha256=CqGGDy-MUqe1VfTdbudE2_t8cbTH8-mFSmg2j0K2XJI,2554
|
|
68
|
+
codexloop/infrastructure/logging.py,sha256=hkTYprWGX5CQutAbNV-KoQtNjQCobfU9U9N1UQYjIP0,3852
|
|
69
|
+
codexloop/infrastructure/notify.py,sha256=M-ESKklX8z2yI4jOB4aSESfXT83Qe8mWFmpF7VP2pSI,1009
|
|
70
|
+
codexloop/infrastructure/progress.py,sha256=ASYX88gol3c4FVrxM9cdITQncsLtNsN0uJl4GCe8Zg8,511
|
|
71
|
+
codexloop/infrastructure/redact.py,sha256=N_NJ_rfVLJK_UKIHNlws4ahpPKHCH-Ed7YSvMxkQtto,1444
|
|
72
|
+
codexloop/infrastructure/rollout.py,sha256=4bJcaSKCHMY_brVNvrTWpafGhOIrHgx7C6Q_2gBs3V0,3651
|
|
73
|
+
codexloop/infrastructure/rundir.py,sha256=ECNXaFRQaqAdNdClImCP7dddhJOcOZ2EnhH02uolkGw,1971
|
|
74
|
+
codexloop/infrastructure/snapshot.py,sha256=S36JXFZTV93KnR3CB23dcVcOK4hnruG8J321noWFIsw,1294
|
|
75
|
+
codexloop/infrastructure/state.py,sha256=FsXioTxFxlwKCI7bFNAHRuwu2ptto8mTtrIvCQnmjHA,1024
|
|
76
|
+
codexloop/infrastructure/state_bus.py,sha256=EAdOWTE7jSVOnAEPt6h3B3FKOF3f0hO_YBSrLthI1Q8,741
|
|
77
|
+
codexloop/infrastructure/stream_ui.py,sha256=BPRPEeBv5EelNFq6N-52s-TZWl7XYjPHK8Fh9Vz_3rc,1325
|
|
78
|
+
codexloop/infrastructure/agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
79
|
+
codexloop/infrastructure/agent/argv.py,sha256=kyMUUp7LanjU5IqE6NQLBI0a_p6iCT1NlfIiNqKRwvE,3228
|
|
80
|
+
codexloop/infrastructure/agent/events.py,sha256=UyzhjTa-fjk7HOkcYmxt8c_IhPxBbt3PZQEgAoMcjDM,7942
|
|
81
|
+
codexloop/infrastructure/agent/gateway.py,sha256=V9kIK7_YLNvnBR137QuyVmqPrbhpHmnVEjw6gj1DKDA,7121
|
|
82
|
+
codexloop/infrastructure/agent/probe.py,sha256=kl6ez8ARpUSZJlP_GCEFnyTAne7GDdRCakh6PwZv3Nc,2902
|
|
83
|
+
codexloop/infrastructure/agent/process.py,sha256=ulVSR2hCybZMEKlm-utC4okEFwr3Vbfn1SuGF2m67i0,6471
|
|
84
|
+
codexloop/infrastructure/agent/schema.py,sha256=NrfVCbKisoEjz4Rr98SYapqprjIxRGhENbfNUa_YQ20,982
|
|
85
|
+
codexloop/infrastructure/agent/scripted.py,sha256=LlYxE7d5a26rpb9sZ2M8Q2lPuCS5CO61fdTywAums_U,7242
|
|
86
|
+
codexloop/infrastructure/agent/translate.py,sha256=GB5RmH5ZB3LifAFglIrmgBHyNOP3R5Ml5mtvCZLjXhE,3828
|
|
87
|
+
codexloop/infrastructure/api/__init__.py,sha256=BLX440wm2CaPwhWDs0zvGQQYYGVF401F4VDxGv5I8c8,633
|
|
88
|
+
codexloop/infrastructure/api/api_baseline.json,sha256=RF4ly4BIwQoOlH-yBJJrFcb9ydIIwgxZ6sxEzWVymec,12569
|
|
89
|
+
codexloop/infrastructure/api/binder.py,sha256=3OkwBgsFZULMAoUx7EjWsrUauCB0wXl0UmlnMsEMeV8,6044
|
|
90
|
+
codexloop/infrastructure/api/gateway.py,sha256=LVbdg_EpI2kykbPSj4T-QECz61P-Efh-g-UuvaEOcIk,4563
|
|
91
|
+
codexloop/infrastructure/api/introspect.py,sha256=6t1B21hH8JQaxybYkrlO8V5Rntur2CmJltxpVsCxk2w,8619
|
|
92
|
+
codexloop/infrastructure/api/json_io.py,sha256=e3wWHJap6KPgD7IQAQgDnc1b7ow-Bx3VHh0nX8CR2CI,875
|
|
93
|
+
codexloop/infrastructure/api/params.py,sha256=wN76IexGnuc5uOvMITtIfS9DAuPjH-jWDu_2CUmJffY,4815
|
|
94
|
+
codexloop/infrastructure/api/providers.py,sha256=m22F2J00ldhsAQb-ichQxuEWjWxCDT2nyXv3B0FvaiA,2880
|
|
95
|
+
codexloop/infrastructure/api/registry.py,sha256=Mq8hIL1Y4E-LTttxGqz8CMMFBvO71C5mO12wwxoFjho,310
|
|
96
|
+
codexloop/infrastructure/appserver/__init__.py,sha256=vlql_zsE4M95mHwepHOyzY5VLRkY8DyTql87OJO1TFQ,312
|
|
97
|
+
codexloop/infrastructure/appserver/client.py,sha256=N8_HcmZj5NSaUOX-g56XM0yLqM4-t1Tz3ZYecc0nw-o,8814
|
|
98
|
+
codexloop/infrastructure/appserver/gateway.py,sha256=rTz40nXycJCsePCym0xvZ1lyizsxqJcmm-pqaZaJi9k,17272
|
|
99
|
+
codexloop/infrastructure/appserver/ratelimits.py,sha256=btP4CCCdK4bK7uHY1_yIkM6tbbkf6LpPqqr7P4gdjEU,3367
|
|
100
|
+
codexloop-0.1.0.dist-info/METADATA,sha256=lYJKWEXPSfonrT9BqQN0myk8oOcxzv9iKyfhSgFuXWA,3976
|
|
101
|
+
codexloop-0.1.0.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
|
|
102
|
+
codexloop-0.1.0.dist-info/entry_points.txt,sha256=5iJcKqQo3HWVfkLLMLFxGLrH58gJBmMZ760Caid0uuc,53
|
|
103
|
+
codexloop-0.1.0.dist-info/licenses/LICENSE,sha256=9ZRUKk2Y2P5Gwro4cQoxhI5sur1Gy7vd5hbgRXcz2Sg,1081
|
|
104
|
+
codexloop-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Adam Matthew Steinberger
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|