codexloop 0.1.0__tar.gz → 0.2.0__tar.gz

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.
Files changed (239) hide show
  1. {codexloop-0.1.0 → codexloop-0.2.0}/.github/workflows/ci.yml +12 -0
  2. codexloop-0.2.0/.github/workflows/docs.yml +40 -0
  3. {codexloop-0.1.0 → codexloop-0.2.0}/.github/workflows/publish-testpypi.yml +1 -0
  4. {codexloop-0.1.0 → codexloop-0.2.0}/.github/workflows/release-please.yml +11 -8
  5. {codexloop-0.1.0 → codexloop-0.2.0}/.gitignore +1 -0
  6. codexloop-0.2.0/.release-please-manifest.json +3 -0
  7. codexloop-0.2.0/CHANGELOG.md +110 -0
  8. {codexloop-0.1.0 → codexloop-0.2.0}/PKG-INFO +13 -5
  9. {codexloop-0.1.0 → codexloop-0.2.0}/README.md +12 -4
  10. codexloop-0.2.0/docs/publishing.md +74 -0
  11. codexloop-0.2.0/mkdocs.yml +44 -0
  12. {codexloop-0.1.0 → codexloop-0.2.0}/pyproject.toml +1 -1
  13. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/__init__.py +1 -1
  14. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/git_savepoints.py +5 -1
  15. {codexloop-0.1.0 → codexloop-0.2.0}/tests/cli/test_app.py +3 -1
  16. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/test_coverage_boost.py +19 -0
  17. codexloop-0.1.0/.release-please-manifest.json +0 -3
  18. codexloop-0.1.0/CHANGELOG.md +0 -42
  19. codexloop-0.1.0/docs/publishing.md +0 -65
  20. codexloop-0.1.0/mkdocs.yml +0 -28
  21. {codexloop-0.1.0 → codexloop-0.2.0}/.agents/skills/codexloop-run/SKILL.md +0 -0
  22. {codexloop-0.1.0 → codexloop-0.2.0}/.claude/skills/codexloop-run/SKILL.md +0 -0
  23. {codexloop-0.1.0 → codexloop-0.2.0}/.cursor/rules/codexloop-run.mdc +0 -0
  24. {codexloop-0.1.0 → codexloop-0.2.0}/.editorconfig +0 -0
  25. {codexloop-0.1.0 → codexloop-0.2.0}/.github/CODEOWNERS +0 -0
  26. {codexloop-0.1.0 → codexloop-0.2.0}/.pre-commit-config.yaml +0 -0
  27. {codexloop-0.1.0 → codexloop-0.2.0}/AGENTS.md +0 -0
  28. {codexloop-0.1.0 → codexloop-0.2.0}/CLAUDE.md +0 -0
  29. {codexloop-0.1.0 → codexloop-0.2.0}/CODE_OF_CONDUCT.md +0 -0
  30. {codexloop-0.1.0 → codexloop-0.2.0}/CONTRIBUTING.md +0 -0
  31. {codexloop-0.1.0 → codexloop-0.2.0}/LICENSE +0 -0
  32. {codexloop-0.1.0 → codexloop-0.2.0}/SECURITY.md +0 -0
  33. {codexloop-0.1.0 → codexloop-0.2.0}/docs/architecture/adr/0001-onion-import-linter.md +0 -0
  34. {codexloop-0.1.0 → codexloop-0.2.0}/docs/architecture/adr/0002-subprocess-codex-exec.md +0 -0
  35. {codexloop-0.1.0 → codexloop-0.2.0}/docs/architecture/adr/0003-credits-exhausted.md +0 -0
  36. {codexloop-0.1.0 → codexloop-0.2.0}/docs/architecture/adr/0004-adaptive-probe-loop.md +0 -0
  37. {codexloop-0.1.0 → codexloop-0.2.0}/docs/architecture/adr/0005-layered-capacity-probe.md +0 -0
  38. {codexloop-0.1.0 → codexloop-0.2.0}/docs/architecture/adr/0006-generated-openai-rest.md +0 -0
  39. {codexloop-0.1.0 → codexloop-0.2.0}/docs/architecture/adr/0007-default-approval-sandbox.md +0 -0
  40. {codexloop-0.1.0 → codexloop-0.2.0}/docs/architecture/adr/0008-policy-via-c-flags.md +0 -0
  41. {codexloop-0.1.0 → codexloop-0.2.0}/docs/architecture/adr/0009-optional-app-server.md +0 -0
  42. {codexloop-0.1.0 → codexloop-0.2.0}/docs/architecture/adr/0010-rollout-best-effort.md +0 -0
  43. {codexloop-0.1.0 → codexloop-0.2.0}/docs/architecture/adr/0011-never-consume-resets.md +0 -0
  44. {codexloop-0.1.0 → codexloop-0.2.0}/docs/architecture/adr/0012-minimum-codex-version.md +0 -0
  45. {codexloop-0.1.0 → codexloop-0.2.0}/docs/architecture/adr/index.md +0 -0
  46. {codexloop-0.1.0 → codexloop-0.2.0}/docs/architecture/index.md +0 -0
  47. {codexloop-0.1.0 → codexloop-0.2.0}/docs/contributing.md +0 -0
  48. {codexloop-0.1.0 → codexloop-0.2.0}/docs/getting-started.md +0 -0
  49. {codexloop-0.1.0 → codexloop-0.2.0}/docs/guides/rest-api-surface.md +0 -0
  50. {codexloop-0.1.0 → codexloop-0.2.0}/docs/index.md +0 -0
  51. {codexloop-0.1.0 → codexloop-0.2.0}/docs/plans/_shared-transplant-outline.md +0 -0
  52. {codexloop-0.1.0 → codexloop-0.2.0}/docs/plans/architecture-and-roadmap.md +0 -0
  53. {codexloop-0.1.0 → codexloop-0.2.0}/docs/plans/research-notes.md +0 -0
  54. {codexloop-0.1.0 → codexloop-0.2.0}/docs/reference/cli.md +0 -0
  55. {codexloop-0.1.0 → codexloop-0.2.0}/docs/superpowers/plans/2026-08-13-codexloop-implementation.md +0 -0
  56. {codexloop-0.1.0 → codexloop-0.2.0}/release-please-config.json +0 -0
  57. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/application/__init__.py +0 -0
  58. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/application/dto.py +0 -0
  59. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/application/ports.py +0 -0
  60. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/application/runner.py +0 -0
  61. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/application/usecases/__init__.py +0 -0
  62. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/application/usecases/doctor.py +0 -0
  63. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/application/usecases/list_threads.py +0 -0
  64. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/application/usecases/preflight.py +0 -0
  65. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/application/usecases/resume_thread.py +0 -0
  66. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/application/usecases/run_control.py +0 -0
  67. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/application/usecases/run_plan.py +0 -0
  68. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/bootstrap.py +0 -0
  69. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/cli/__init__.py +0 -0
  70. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/cli/app.py +0 -0
  71. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/cli/asyncio.py +0 -0
  72. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/cli/commands/__init__.py +0 -0
  73. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/cli/commands/approval_cmd.py +0 -0
  74. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/cli/commands/capacity.py +0 -0
  75. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/cli/commands/cwd_cmd.py +0 -0
  76. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/cli/commands/doctor.py +0 -0
  77. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/cli/commands/effort_cmd.py +0 -0
  78. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/cli/commands/logs.py +0 -0
  79. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/cli/commands/model_cmd.py +0 -0
  80. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/cli/commands/prompt.py +0 -0
  81. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/cli/commands/reset.py +0 -0
  82. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/cli/commands/resume.py +0 -0
  83. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/cli/commands/run.py +0 -0
  84. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/cli/commands/runs.py +0 -0
  85. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/cli/commands/sandbox_cmd.py +0 -0
  86. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/cli/commands/savepoints.py +0 -0
  87. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/cli/commands/snapshot.py +0 -0
  88. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/cli/commands/status.py +0 -0
  89. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/cli/commands/stop.py +0 -0
  90. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/cli/commands/threads.py +0 -0
  91. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/cli/commands/unwind.py +0 -0
  92. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/cli/commands/watch.py +0 -0
  93. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/cli/render.py +0 -0
  94. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/domain/__init__.py +0 -0
  95. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/domain/approval.py +0 -0
  96. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/domain/backoff.py +0 -0
  97. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/domain/budget.py +0 -0
  98. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/domain/capacity.py +0 -0
  99. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/domain/classify.py +0 -0
  100. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/domain/completion.py +0 -0
  101. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/domain/control.py +0 -0
  102. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/domain/error_codes.py +0 -0
  103. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/domain/errors.py +0 -0
  104. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/domain/loop.py +0 -0
  105. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/domain/model_profile.py +0 -0
  106. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/domain/plan.py +0 -0
  107. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/domain/savepoint.py +0 -0
  108. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/domain/savepoint_message.py +0 -0
  109. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/domain/session.py +0 -0
  110. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/domain/signals.py +0 -0
  111. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/domain/waiting.py +0 -0
  112. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/__init__.py +0 -0
  113. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/agent/__init__.py +0 -0
  114. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/agent/argv.py +0 -0
  115. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/agent/events.py +0 -0
  116. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/agent/gateway.py +0 -0
  117. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/agent/probe.py +0 -0
  118. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/agent/process.py +0 -0
  119. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/agent/schema.py +0 -0
  120. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/agent/scripted.py +0 -0
  121. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/agent/translate.py +0 -0
  122. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/api/__init__.py +0 -0
  123. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/api/api_baseline.json +0 -0
  124. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/api/binder.py +0 -0
  125. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/api/gateway.py +0 -0
  126. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/api/introspect.py +0 -0
  127. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/api/json_io.py +0 -0
  128. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/api/params.py +0 -0
  129. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/api/providers.py +0 -0
  130. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/api/registry.py +0 -0
  131. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/appserver/__init__.py +0 -0
  132. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/appserver/client.py +0 -0
  133. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/appserver/gateway.py +0 -0
  134. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/appserver/ratelimits.py +0 -0
  135. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/audit.py +0 -0
  136. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/capacity_probe.py +0 -0
  137. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/clock.py +0 -0
  138. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/config.py +0 -0
  139. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/control.py +0 -0
  140. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/doctor_env.py +0 -0
  141. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/events.py +0 -0
  142. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/lock.py +0 -0
  143. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/logging.py +0 -0
  144. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/notify.py +0 -0
  145. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/progress.py +0 -0
  146. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/redact.py +0 -0
  147. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/rollout.py +0 -0
  148. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/rundir.py +0 -0
  149. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/snapshot.py +0 -0
  150. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/state.py +0 -0
  151. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/state_bus.py +0 -0
  152. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/infrastructure/stream_ui.py +0 -0
  153. {codexloop-0.1.0 → codexloop-0.2.0}/src/codexloop/py.typed +0 -0
  154. {codexloop-0.1.0 → codexloop-0.2.0}/tests/__init__.py +0 -0
  155. {codexloop-0.1.0 → codexloop-0.2.0}/tests/application/__init__.py +0 -0
  156. {codexloop-0.1.0 → codexloop-0.2.0}/tests/application/fakes.py +0 -0
  157. {codexloop-0.1.0 → codexloop-0.2.0}/tests/application/test_doctor.py +0 -0
  158. {codexloop-0.1.0 → codexloop-0.2.0}/tests/application/test_ports.py +0 -0
  159. {codexloop-0.1.0 → codexloop-0.2.0}/tests/application/test_runner.py +0 -0
  160. {codexloop-0.1.0 → codexloop-0.2.0}/tests/application/test_usecases.py +0 -0
  161. {codexloop-0.1.0 → codexloop-0.2.0}/tests/application/test_waiting_runner.py +0 -0
  162. {codexloop-0.1.0 → codexloop-0.2.0}/tests/cli/__init__.py +0 -0
  163. {codexloop-0.1.0 → codexloop-0.2.0}/tests/cli/test_api.py +0 -0
  164. {codexloop-0.1.0 → codexloop-0.2.0}/tests/cli/test_asyncio.py +0 -0
  165. {codexloop-0.1.0 → codexloop-0.2.0}/tests/cli/test_e2e_shim.py +0 -0
  166. {codexloop-0.1.0 → codexloop-0.2.0}/tests/cli/test_ops_commands.py +0 -0
  167. {codexloop-0.1.0 → codexloop-0.2.0}/tests/conftest.py +0 -0
  168. {codexloop-0.1.0 → codexloop-0.2.0}/tests/domain/__init__.py +0 -0
  169. {codexloop-0.1.0 → codexloop-0.2.0}/tests/domain/strategies.py +0 -0
  170. {codexloop-0.1.0 → codexloop-0.2.0}/tests/domain/test_approval.py +0 -0
  171. {codexloop-0.1.0 → codexloop-0.2.0}/tests/domain/test_backoff.py +0 -0
  172. {codexloop-0.1.0 → codexloop-0.2.0}/tests/domain/test_budget.py +0 -0
  173. {codexloop-0.1.0 → codexloop-0.2.0}/tests/domain/test_capacity.py +0 -0
  174. {codexloop-0.1.0 → codexloop-0.2.0}/tests/domain/test_classify.py +0 -0
  175. {codexloop-0.1.0 → codexloop-0.2.0}/tests/domain/test_completion.py +0 -0
  176. {codexloop-0.1.0 → codexloop-0.2.0}/tests/domain/test_control.py +0 -0
  177. {codexloop-0.1.0 → codexloop-0.2.0}/tests/domain/test_error_codes.py +0 -0
  178. {codexloop-0.1.0 → codexloop-0.2.0}/tests/domain/test_loop.py +0 -0
  179. {codexloop-0.1.0 → codexloop-0.2.0}/tests/domain/test_model_profile.py +0 -0
  180. {codexloop-0.1.0 → codexloop-0.2.0}/tests/domain/test_plan.py +0 -0
  181. {codexloop-0.1.0 → codexloop-0.2.0}/tests/domain/test_savepoint.py +0 -0
  182. {codexloop-0.1.0 → codexloop-0.2.0}/tests/domain/test_session.py +0 -0
  183. {codexloop-0.1.0 → codexloop-0.2.0}/tests/domain/test_waiting.py +0 -0
  184. {codexloop-0.1.0 → codexloop-0.2.0}/tests/fixtures/jsonl/README.md +0 -0
  185. {codexloop-0.1.0 → codexloop-0.2.0}/tests/fixtures/jsonl/clean_completion.jsonl +0 -0
  186. {codexloop-0.1.0 → codexloop-0.2.0}/tests/fixtures/jsonl/done_with_marker.jsonl +0 -0
  187. {codexloop-0.1.0 → codexloop-0.2.0}/tests/fixtures/jsonl/huge_line.jsonl +0 -0
  188. {codexloop-0.1.0 → codexloop-0.2.0}/tests/fixtures/jsonl/malformed_line.jsonl +0 -0
  189. {codexloop-0.1.0 → codexloop-0.2.0}/tests/fixtures/jsonl/tool_heavy.jsonl +0 -0
  190. {codexloop-0.1.0 → codexloop-0.2.0}/tests/fixtures/jsonl/truncated_stream.jsonl +0 -0
  191. {codexloop-0.1.0 → codexloop-0.2.0}/tests/fixtures/jsonl/turn_failed_429_quota.jsonl +0 -0
  192. {codexloop-0.1.0 → codexloop-0.2.0}/tests/fixtures/jsonl/turn_failed_429_window.jsonl +0 -0
  193. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/__init__.py +0 -0
  194. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/api/__init__.py +0 -0
  195. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/api/test_binder.py +0 -0
  196. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/api/test_drift.py +0 -0
  197. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/api/test_gateway.py +0 -0
  198. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/api/test_introspect.py +0 -0
  199. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/api/test_json_io.py +0 -0
  200. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/api/test_params.py +0 -0
  201. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/api/test_params_extra.py +0 -0
  202. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/api/test_providers.py +0 -0
  203. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/api/test_providers_gateway_extra.py +0 -0
  204. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/test_appserver.py +0 -0
  205. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/test_appserver_gateway.py +0 -0
  206. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/test_argv.py +0 -0
  207. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/test_capacity_probe.py +0 -0
  208. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/test_config.py +0 -0
  209. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/test_control_and_savepoints.py +0 -0
  210. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/test_doctor_env.py +0 -0
  211. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/test_events.py +0 -0
  212. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/test_gateway.py +0 -0
  213. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/test_lock.py +0 -0
  214. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/test_logging_redact.py +0 -0
  215. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/test_probe.py +0 -0
  216. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/test_process.py +0 -0
  217. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/test_ratelimits_extra.py +0 -0
  218. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/test_rollout.py +0 -0
  219. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/test_rundir_state.py +0 -0
  220. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/test_scripted.py +0 -0
  221. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/test_snapshot.py +0 -0
  222. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/test_state_bus.py +0 -0
  223. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/test_stream_ui.py +0 -0
  224. {codexloop-0.1.0 → codexloop-0.2.0}/tests/infrastructure/test_translate.py +0 -0
  225. {codexloop-0.1.0 → codexloop-0.2.0}/tests/live/fixtures/agent_scripts/done.json +0 -0
  226. {codexloop-0.1.0 → codexloop-0.2.0}/tests/live/fixtures/agent_scripts/quota_then_topup.json +0 -0
  227. {codexloop-0.1.0 → codexloop-0.2.0}/tests/live/fixtures/agent_scripts/unknown_429.json +0 -0
  228. {codexloop-0.1.0 → codexloop-0.2.0}/tests/live/fixtures/agent_scripts/wait_long.json +0 -0
  229. {codexloop-0.1.0 → codexloop-0.2.0}/tests/live/fixtures/agent_scripts/window_then_done.json +0 -0
  230. {codexloop-0.1.0 → codexloop-0.2.0}/tests/live/system/conftest.py +0 -0
  231. {codexloop-0.1.0 → codexloop-0.2.0}/tests/live/system/test_matrix_inprocess.py +0 -0
  232. {codexloop-0.1.0 → codexloop-0.2.0}/tests/live/system/test_subprocess_smoke.py +0 -0
  233. {codexloop-0.1.0 → codexloop-0.2.0}/tests/shim/__init__.py +0 -0
  234. {codexloop-0.1.0 → codexloop-0.2.0}/tests/shim/fake_appserver.py +0 -0
  235. {codexloop-0.1.0 → codexloop-0.2.0}/tests/shim/fake_codex.py +0 -0
  236. {codexloop-0.1.0 → codexloop-0.2.0}/tests/shim/test_fake_codex.py +0 -0
  237. {codexloop-0.1.0 → codexloop-0.2.0}/tests/test_bootstrap.py +0 -0
  238. {codexloop-0.1.0 → codexloop-0.2.0}/tests/test_no_vendor_leak.py +0 -0
  239. {codexloop-0.1.0 → codexloop-0.2.0}/tests/test_packaging.py +0 -0
@@ -37,6 +37,18 @@ jobs:
37
37
  - run: pip-audit
38
38
  - run: pytest --cov-report=term-missing
39
39
 
40
+ docs:
41
+ name: MkDocs builds strictly
42
+ runs-on: ubuntu-latest
43
+ steps:
44
+ - uses: actions/checkout@v7.0.1
45
+ - uses: actions/setup-python@v7.0.0
46
+ with:
47
+ python-version: "3.12"
48
+ - run: python -m pip install --upgrade pip
49
+ - run: pip install -e ".[docs]"
50
+ - run: mkdocs build --strict
51
+
40
52
  build:
41
53
  name: Package builds and is installable
42
54
  runs-on: ubuntu-latest
@@ -0,0 +1,40 @@
1
+ name: Docs
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: read
10
+ pages: write
11
+ id-token: write
12
+
13
+ concurrency:
14
+ group: pages
15
+ cancel-in-progress: false
16
+
17
+ jobs:
18
+ build:
19
+ runs-on: ubuntu-latest
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+ - uses: actions/setup-python@v5
23
+ with:
24
+ python-version: "3.12"
25
+ - run: python -m pip install --upgrade pip
26
+ - run: pip install -e ".[docs]"
27
+ - run: mkdocs build --strict
28
+ - uses: actions/upload-pages-artifact@v3
29
+ with:
30
+ path: site
31
+
32
+ deploy:
33
+ needs: build
34
+ runs-on: ubuntu-latest
35
+ environment:
36
+ name: github-pages
37
+ url: ${{ steps.deployment.outputs.page_url }}
38
+ steps:
39
+ - id: deployment
40
+ uses: actions/deploy-pages@v4
@@ -16,6 +16,7 @@ concurrency:
16
16
  jobs:
17
17
  publish:
18
18
  name: Build and publish to TestPyPI
19
+ if: ${{ github.ref == 'refs/heads/develop' }}
19
20
  runs-on: ubuntu-latest
20
21
  environment: testpypi
21
22
  steps:
@@ -5,8 +5,8 @@ on:
5
5
  branches: [main]
6
6
  workflow_dispatch:
7
7
  inputs:
8
- publish_to_testpypi:
9
- description: "Also build and publish this commit to TestPyPI (Trusted Publishing)."
8
+ publish_to_pypi:
9
+ description: "Build and publish ref to PyPI (Trusted Publishing). Use after tagging or to retry a release."
10
10
  type: boolean
11
11
  default: false
12
12
 
@@ -22,9 +22,12 @@ jobs:
22
22
  release_created: ${{ steps.release.outputs.release_created }}
23
23
  tag_name: ${{ steps.release.outputs.tag_name }}
24
24
  steps:
25
- - uses: googleapis/release-please-action@v4
25
+ - uses: googleapis/release-please-action@v5
26
26
  id: release
27
27
  with:
28
+ # Repo default branch is develop; releases must target main only
29
+ # (feat → develop → TestPyPI → main → tag/PyPI).
30
+ target-branch: main
28
31
  release-type: python
29
32
  config-file: release-please-config.json
30
33
  manifest-file: .release-please-manifest.json
@@ -52,15 +55,17 @@ jobs:
52
55
  packages-dir: dist/
53
56
  print-hash: true
54
57
 
55
- publish-testpypi-manual:
56
- if: ${{ github.event_name == 'workflow_dispatch' && inputs.publish_to_testpypi }}
58
+ publish-pypi-manual:
59
+ if: ${{ github.event_name == 'workflow_dispatch' && inputs.publish_to_pypi }}
57
60
  runs-on: ubuntu-latest
58
- environment: testpypi
61
+ environment: pypi
59
62
  permissions:
60
63
  id-token: write
61
64
  contents: read
62
65
  steps:
63
66
  - uses: actions/checkout@v4
67
+ with:
68
+ ref: v0.1.0
64
69
  - uses: actions/setup-python@v5
65
70
  with:
66
71
  python-version: "3.12"
@@ -69,7 +74,5 @@ jobs:
69
74
  - run: twine check --strict dist/*
70
75
  - uses: pypa/gh-action-pypi-publish@release/v1
71
76
  with:
72
- repository-url: https://test.pypi.org/legacy/
73
77
  packages-dir: dist/
74
- skip-existing: true
75
78
  print-hash: true
@@ -46,3 +46,4 @@ site/
46
46
 
47
47
  # --- SDD scratch ---
48
48
  .superpowers/
49
+ .venv-docs/
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.2.0"
3
+ }
@@ -0,0 +1,110 @@
1
+ # Changelog
2
+
3
+ ## [0.2.0](https://github.com/adammatthewsteinberger/codexloop/compare/v0.1.1...v0.2.0) (2026-08-14)
4
+
5
+
6
+ ### Features
7
+
8
+ * add app-server rate-limit probe client ([a30ef93](https://github.com/adammatthewsteinberger/codexloop/commit/a30ef9377685ef9aea8f5096e1759b0f6293574e))
9
+ * add application ports and fakes ([33e721d](https://github.com/adammatthewsteinberger/codexloop/commit/33e721d0dab21b38c614ab71ea7c3e47a8126fb3))
10
+ * add autonomous runner and run/resume use cases ([bd36f45](https://github.com/adammatthewsteinberger/codexloop/commit/bd36f457548c5969f0fd37453c2d1ab5727d3302))
11
+ * add backoff and adaptive wait policy ([43c70c6](https://github.com/adammatthewsteinberger/codexloop/commit/43c70c68396255e10c61907497c53dd0d1c2ba63))
12
+ * add bootstrap and core CLI commands ([6b6aafc](https://github.com/adammatthewsteinberger/codexloop/commit/6b6aafc94f8d2513282389f154682b1b5a97bcee))
13
+ * add capacity value objects ([1aa3fed](https://github.com/adammatthewsteinberger/codexloop/commit/1aa3fede743d6c5db518f869d03826788c64da5b))
14
+ * add clock, logging, config, rundir, state, and lock adapters ([8f7e4ad](https://github.com/adammatthewsteinberger/codexloop/commit/8f7e4ad1aad0f9a754e7ff5777898bfe5a35c5cd))
15
+ * add codex argv builder ([42ab842](https://github.com/adammatthewsteinberger/codexloop/commit/42ab8426e676b0c6b59bb655bfc94e4a607338ba))
16
+ * add control plane, savepoints, and ops CLI ([512e03f](https://github.com/adammatthewsteinberger/codexloop/commit/512e03f24eddf226425326b992eacc4732f1bc7b))
17
+ * add ephemeral read-only exec capacity probe ([427620b](https://github.com/adammatthewsteinberger/codexloop/commit/427620bda645389caf571bcef010d269d3457093))
18
+ * add error hierarchy and OpenAI error-code taxonomy ([1bf5aa2](https://github.com/adammatthewsteinberger/codexloop/commit/1bf5aa2f2805c80aeba0f37fbe6da1dcb4a59585))
19
+ * add generated OpenAI REST CLI surface with drift gate ([53320f8](https://github.com/adammatthewsteinberger/codexloop/commit/53320f82512869b43075d6eeaf3f6fe73a06a3dd))
20
+ * add optional app-server gateway, stream UI, docs, and release scaffolding ([23bfddf](https://github.com/adammatthewsteinberger/codexloop/commit/23bfddfb169cfb37e8fe60a9a80bd7f9b644bba9))
21
+ * add plan, budget, session, profile, approval, and control types ([07a8188](https://github.com/adammatthewsteinberger/codexloop/commit/07a8188207fa6fbac5f85114d891b266b6be1bf9))
22
+ * add read-only CODEX_HOME rollout tail ([071d6ab](https://github.com/adammatthewsteinberger/codexloop/commit/071d6abe526935893d7d330909e96a308e5203b2))
23
+ * add run-loop state machine ([582144f](https://github.com/adammatthewsteinberger/codexloop/commit/582144fcd2b5d3c327f6af36c74307a9a8818966))
24
+ * add scripted system harness and test-agent gate ([68a7ebf](https://github.com/adammatthewsteinberger/codexloop/commit/68a7ebf9483013f5e7fae4ff98ff2b0f5da843f0))
25
+ * add three-layer completion evaluation ([eee2cc3](https://github.com/adammatthewsteinberger/codexloop/commit/eee2cc3a70562126c438e1a1ba842abca9aa0db6))
26
+ * classify turn signals into capacity states ([f7c4162](https://github.com/adammatthewsteinberger/codexloop/commit/f7c4162048b62f83a7b7ea3f99474605f18376ef))
27
+ * implement codexloop M1–M5 (onion runner + REST + docs) ([1dbef91](https://github.com/adammatthewsteinberger/codexloop/commit/1dbef9118097d8b8210f6a770df8c4c05956f6ce))
28
+ * parse codex exec JSONL events ([1cdc76c](https://github.com/adammatthewsteinberger/codexloop/commit/1cdc76c754f0e0f023f7dc94472be59f9776d3f5))
29
+ * supervise codex subprocess with concurrent pumps ([1c95f6e](https://github.com/adammatthewsteinberger/codexloop/commit/1c95f6e6fe628daefe0256e5ba5fb921bfd595a5))
30
+ * translate JSONL and drive codex exec gateway ([6a1842c](https://github.com/adammatthewsteinberger/codexloop/commit/6a1842c3bab3b9eb57d052b2bb8f1c45b919b69f))
31
+ * wire composite capacity probe and adaptive wait loop ([ab682b1](https://github.com/adammatthewsteinberger/codexloop/commit/ab682b16130829e3ae7a523597213c33509dec22))
32
+
33
+
34
+ ### Bug Fixes
35
+
36
+ * jitter throttle waits above Retry-After ([666a4e6](https://github.com/adammatthewsteinberger/codexloop/commit/666a4e6c3d73f277946e866d33866091c225e1c8))
37
+ * only break session locks for known-dead pids ([712b0f4](https://github.com/adammatthewsteinberger/codexloop/commit/712b0f4a4b25d83ba27c0ca53d8278e6961efbd9))
38
+ * pin release-please to main ([4c974a2](https://github.com/adammatthewsteinberger/codexloop/commit/4c974a243f98d0790325929fd124c4aca72f04f7))
39
+ * pin release-please to main and Node 24 action ([cf19789](https://github.com/adammatthewsteinberger/codexloop/commit/cf19789c9ed4fc179f88ef6176f8b05859d05cb8))
40
+ * preserve remaining work across capacity-rejected turns ([d2d10c3](https://github.com/adammatthewsteinberger/codexloop/commit/d2d10c36a93084a36f48509433d9bb6865172fde))
41
+ * resolve all-digit SHA prefixes as save-point SHAs ([43cdde7](https://github.com/adammatthewsteinberger/codexloop/commit/43cdde7d5f65910c06ef6273e64987a391ce0488))
42
+ * seal onion contracts and order drain before signals ([cecf827](https://github.com/adammatthewsteinberger/codexloop/commit/cecf827e841d11df0fb34c71724415970da3ab7d))
43
+ * stabilize CI help and process-group cancel tests ([3fe2c6d](https://github.com/adammatthewsteinberger/codexloop/commit/3fe2c6d09f94adb0de528a74364a0d9d177ee77b))
44
+ * terminate fatals, apply mid-run controls, harden ops edges ([9171835](https://github.com/adammatthewsteinberger/codexloop/commit/91718359a07f5e25ffd1366c7ea8bbfba51b0a01))
45
+ * treat ControlCommand as the inbox union and wrap parse errors ([0885204](https://github.com/adammatthewsteinberger/codexloop/commit/08852040d2a48a14eb5b7b750fa5d02bb9314e4b))
46
+ * unstick version CI and keep TestPyPI on develop ([a4cf78e](https://github.com/adammatthewsteinberger/codexloop/commit/a4cf78eb32a622af03f707a5654c8da708a81f83))
47
+ * version CI + TestPyPI only from develop ([01d7695](https://github.com/adammatthewsteinberger/codexloop/commit/01d7695de87849b949ffd6e275b1f79126f9f2c6))
48
+
49
+
50
+ ### Documentation
51
+
52
+ * deploy MkDocs site to GitHub Pages ([bce3384](https://github.com/adammatthewsteinberger/codexloop/commit/bce33843a1eb7f2579fea6d895b9966abcf5f11e))
53
+ * GitHub Pages MkDocs site ([e1c286b](https://github.com/adammatthewsteinberger/codexloop/commit/e1c286bef14b63f5b337548eb99bad94b917f21a))
54
+
55
+ ## [0.1.1](https://github.com/adammatthewsteinberger/codexloop/compare/v0.1.0...v0.1.1) (2026-08-14)
56
+
57
+
58
+ ### Bug Fixes
59
+
60
+ * pin release-please to main ([4c974a2](https://github.com/adammatthewsteinberger/codexloop/commit/4c974a243f98d0790325929fd124c4aca72f04f7))
61
+ * pin release-please to main and Node 24 action ([cf19789](https://github.com/adammatthewsteinberger/codexloop/commit/cf19789c9ed4fc179f88ef6176f8b05859d05cb8))
62
+ * unstick version CI and keep TestPyPI on develop ([a4cf78e](https://github.com/adammatthewsteinberger/codexloop/commit/a4cf78eb32a622af03f707a5654c8da708a81f83))
63
+ * version CI + TestPyPI only from develop ([01d7695](https://github.com/adammatthewsteinberger/codexloop/commit/01d7695de87849b949ffd6e275b1f79126f9f2c6))
64
+
65
+
66
+ ### Documentation
67
+
68
+ * deploy MkDocs site to GitHub Pages ([bce3384](https://github.com/adammatthewsteinberger/codexloop/commit/bce33843a1eb7f2579fea6d895b9966abcf5f11e))
69
+ * GitHub Pages MkDocs site ([e1c286b](https://github.com/adammatthewsteinberger/codexloop/commit/e1c286bef14b63f5b337548eb99bad94b917f21a))
70
+
71
+ ## 0.1.0 (2026-08-13)
72
+
73
+
74
+ ### Features
75
+
76
+ * add app-server rate-limit probe client ([a30ef93](https://github.com/adammatthewsteinberger/codexloop/commit/a30ef9377685ef9aea8f5096e1759b0f6293574e))
77
+ * add application ports and fakes ([33e721d](https://github.com/adammatthewsteinberger/codexloop/commit/33e721d0dab21b38c614ab71ea7c3e47a8126fb3))
78
+ * add autonomous runner and run/resume use cases ([bd36f45](https://github.com/adammatthewsteinberger/codexloop/commit/bd36f457548c5969f0fd37453c2d1ab5727d3302))
79
+ * add backoff and adaptive wait policy ([43c70c6](https://github.com/adammatthewsteinberger/codexloop/commit/43c70c68396255e10c61907497c53dd0d1c2ba63))
80
+ * add bootstrap and core CLI commands ([6b6aafc](https://github.com/adammatthewsteinberger/codexloop/commit/6b6aafc94f8d2513282389f154682b1b5a97bcee))
81
+ * add capacity value objects ([1aa3fed](https://github.com/adammatthewsteinberger/codexloop/commit/1aa3fede743d6c5db518f869d03826788c64da5b))
82
+ * add clock, logging, config, rundir, state, and lock adapters ([8f7e4ad](https://github.com/adammatthewsteinberger/codexloop/commit/8f7e4ad1aad0f9a754e7ff5777898bfe5a35c5cd))
83
+ * add codex argv builder ([42ab842](https://github.com/adammatthewsteinberger/codexloop/commit/42ab8426e676b0c6b59bb655bfc94e4a607338ba))
84
+ * add control plane, savepoints, and ops CLI ([512e03f](https://github.com/adammatthewsteinberger/codexloop/commit/512e03f24eddf226425326b992eacc4732f1bc7b))
85
+ * add ephemeral read-only exec capacity probe ([427620b](https://github.com/adammatthewsteinberger/codexloop/commit/427620bda645389caf571bcef010d269d3457093))
86
+ * add error hierarchy and OpenAI error-code taxonomy ([1bf5aa2](https://github.com/adammatthewsteinberger/codexloop/commit/1bf5aa2f2805c80aeba0f37fbe6da1dcb4a59585))
87
+ * add generated OpenAI REST CLI surface with drift gate ([53320f8](https://github.com/adammatthewsteinberger/codexloop/commit/53320f82512869b43075d6eeaf3f6fe73a06a3dd))
88
+ * add optional app-server gateway, stream UI, docs, and release scaffolding ([23bfddf](https://github.com/adammatthewsteinberger/codexloop/commit/23bfddfb169cfb37e8fe60a9a80bd7f9b644bba9))
89
+ * add plan, budget, session, profile, approval, and control types ([07a8188](https://github.com/adammatthewsteinberger/codexloop/commit/07a8188207fa6fbac5f85114d891b266b6be1bf9))
90
+ * add read-only CODEX_HOME rollout tail ([071d6ab](https://github.com/adammatthewsteinberger/codexloop/commit/071d6abe526935893d7d330909e96a308e5203b2))
91
+ * add run-loop state machine ([582144f](https://github.com/adammatthewsteinberger/codexloop/commit/582144fcd2b5d3c327f6af36c74307a9a8818966))
92
+ * add scripted system harness and test-agent gate ([68a7ebf](https://github.com/adammatthewsteinberger/codexloop/commit/68a7ebf9483013f5e7fae4ff98ff2b0f5da843f0))
93
+ * add three-layer completion evaluation ([eee2cc3](https://github.com/adammatthewsteinberger/codexloop/commit/eee2cc3a70562126c438e1a1ba842abca9aa0db6))
94
+ * classify turn signals into capacity states ([f7c4162](https://github.com/adammatthewsteinberger/codexloop/commit/f7c4162048b62f83a7b7ea3f99474605f18376ef))
95
+ * implement codexloop M1–M5 (onion runner + REST + docs) ([1dbef91](https://github.com/adammatthewsteinberger/codexloop/commit/1dbef9118097d8b8210f6a770df8c4c05956f6ce))
96
+ * parse codex exec JSONL events ([1cdc76c](https://github.com/adammatthewsteinberger/codexloop/commit/1cdc76c754f0e0f023f7dc94472be59f9776d3f5))
97
+ * supervise codex subprocess with concurrent pumps ([1c95f6e](https://github.com/adammatthewsteinberger/codexloop/commit/1c95f6e6fe628daefe0256e5ba5fb921bfd595a5))
98
+ * translate JSONL and drive codex exec gateway ([6a1842c](https://github.com/adammatthewsteinberger/codexloop/commit/6a1842c3bab3b9eb57d052b2bb8f1c45b919b69f))
99
+ * wire composite capacity probe and adaptive wait loop ([ab682b1](https://github.com/adammatthewsteinberger/codexloop/commit/ab682b16130829e3ae7a523597213c33509dec22))
100
+
101
+
102
+ ### Bug Fixes
103
+
104
+ * jitter throttle waits above Retry-After ([666a4e6](https://github.com/adammatthewsteinberger/codexloop/commit/666a4e6c3d73f277946e866d33866091c225e1c8))
105
+ * only break session locks for known-dead pids ([712b0f4](https://github.com/adammatthewsteinberger/codexloop/commit/712b0f4a4b25d83ba27c0ca53d8278e6961efbd9))
106
+ * preserve remaining work across capacity-rejected turns ([d2d10c3](https://github.com/adammatthewsteinberger/codexloop/commit/d2d10c36a93084a36f48509433d9bb6865172fde))
107
+ * seal onion contracts and order drain before signals ([cecf827](https://github.com/adammatthewsteinberger/codexloop/commit/cecf827e841d11df0fb34c71724415970da3ab7d))
108
+ * stabilize CI help and process-group cancel tests ([3fe2c6d](https://github.com/adammatthewsteinberger/codexloop/commit/3fe2c6d09f94adb0de528a74364a0d9d177ee77b))
109
+ * terminate fatals, apply mid-run controls, harden ops edges ([9171835](https://github.com/adammatthewsteinberger/codexloop/commit/91718359a07f5e25ffd1366c7ea8bbfba51b0a01))
110
+ * treat ControlCommand as the inbox union and wrap parse errors ([0885204](https://github.com/adammatthewsteinberger/codexloop/commit/08852040d2a48a14eb5b7b750fa5d02bb9314e4b))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: codexloop
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
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
5
  Project-URL: Homepage, https://github.com/adammatthewsteinberger/codexloop
6
6
  Project-URL: Repository, https://github.com/adammatthewsteinberger/codexloop
@@ -56,18 +56,26 @@ Autonomous OpenAI Codex / GPT session runner. Same job as
56
56
  a human, and never treat `insufficient_quota` / billing as a waitable
57
57
  `rate_limit_exceeded` window.
58
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.
59
+ **Docs:** https://adammatthewsteinberger.github.io/codexloop/
60
+
61
+ **Status:** M1–M5 on PyPI (`0.1.0`) onion core, exec gateway, capacity probes,
62
+ control plane, generated REST CLI, optional app-server transport with exec
63
+ fallback. MIT-licensed; author Adam Matthew Steinberger.
62
64
 
63
65
  ## Install
64
66
 
65
67
  ```bash
66
- pip install -e ".[dev]"
68
+ pip install codexloop
67
69
  codexloop --version
68
70
  codexloop doctor
69
71
  ```
70
72
 
73
+ For local development:
74
+
75
+ ```bash
76
+ pip install -e ".[dev]"
77
+ ```
78
+
71
79
  ## Quick start
72
80
 
73
81
  ```bash
@@ -5,18 +5,26 @@ Autonomous OpenAI Codex / GPT session runner. Same job as
5
5
  a human, and never treat `insufficient_quota` / billing as a waitable
6
6
  `rate_limit_exceeded` window.
7
7
 
8
- **Status:** M1–M5 implemented on `feat/m1-pure-core` (onion core, exec gateway,
9
- capacity probes, control plane, generated REST CLI, optional app-server transport
10
- with exec fallback). MIT-licensed; author Adam Matthew Steinberger.
8
+ **Docs:** https://adammatthewsteinberger.github.io/codexloop/
9
+
10
+ **Status:** M1–M5 on PyPI (`0.1.0`) onion core, exec gateway, capacity probes,
11
+ control plane, generated REST CLI, optional app-server transport with exec
12
+ fallback. MIT-licensed; author Adam Matthew Steinberger.
11
13
 
12
14
  ## Install
13
15
 
14
16
  ```bash
15
- pip install -e ".[dev]"
17
+ pip install codexloop
16
18
  codexloop --version
17
19
  codexloop doctor
18
20
  ```
19
21
 
22
+ For local development:
23
+
24
+ ```bash
25
+ pip install -e ".[dev]"
26
+ ```
27
+
20
28
  ## Quick start
21
29
 
22
30
  ```bash
@@ -0,0 +1,74 @@
1
+ # Publishing
2
+
3
+ `codexloop` ships via [Trusted Publishing](https://docs.pypi.org/trusted-publishers/)
4
+ (OIDC). No long-lived PyPI API tokens are stored in GitHub.
5
+
6
+ ## Environments
7
+
8
+ | GitHub Environment | Index | Branch / workflow |
9
+ |---|---|---|
10
+ | `testpypi` | https://test.pypi.org | **`develop`** → `.github/workflows/publish-testpypi.yml` |
11
+ | `pypi` | https://pypi.org | **`main`** → `.github/workflows/release-please.yml` (`publish-pypi`) |
12
+
13
+ Create them once (repo **Settings → Environments**), or via API as in the
14
+ setup checklist below.
15
+
16
+ ## One-time Trusted Publisher setup
17
+
18
+ Do this **before** the first upload (pending publisher), signed in as the PyPI
19
+ owner account.
20
+
21
+ ### TestPyPI
22
+
23
+ 1. Open https://test.pypi.org/manage/account/publishing/
24
+ 2. Add a pending publisher:
25
+ - **PyPI Project Name:** `codexloop`
26
+ - **Owner:** `adammatthewsteinberger`
27
+ - **Repository name:** `codexloop`
28
+ - **Workflow name:** `publish-testpypi.yml`
29
+ - **Environment name:** `testpypi`
30
+
31
+ ### PyPI
32
+
33
+ 1. Open https://pypi.org/manage/account/publishing/
34
+ 2. Add a pending publisher:
35
+ - **PyPI Project Name:** `codexloop`
36
+ - **Owner:** `adammatthewsteinberger`
37
+ - **Repository name:** `codexloop`
38
+ - **Workflow name:** `release-please.yml`
39
+ - **Environment name:** `pypi`
40
+
41
+ ## Release flow
42
+
43
+ ```text
44
+ feat/* ──PR──► develop ──auto TestPyPI──► main ──release-please──► PyPI
45
+ ```
46
+
47
+ 1. Land work on `develop`. Every push to `develop` runs **Publish TestPyPI**
48
+ (`publish-testpypi.yml`). Do not publish TestPyPI from `main`.
49
+ 2. Smoke-install from TestPyPI if needed:
50
+ `pip install -i https://test.pypi.org/simple/ --pre codexloop`.
51
+ 3. Merge `develop` → `main` when ready.
52
+ 4. `release-please` opens a release PR against **`main` only**
53
+ (`target-branch: main` in `.github/workflows/release-please.yml`).
54
+ 5. Squash-merge the release PR → GitHub Release + tag → `publish-pypi`
55
+ uploads to **PyPI**. Do not open or merge `chore(develop): release …` PRs.
56
+
57
+ Manual PyPI retry (Trusted Publishing, `main` / tagged release only):
58
+
59
+ ```bash
60
+ gh workflow run release-please.yml -f publish_to_pypi=true
61
+ ```
62
+
63
+ Manual TestPyPI from `develop`:
64
+
65
+ ```bash
66
+ gh workflow run "Publish TestPyPI" --ref develop
67
+ ```
68
+
69
+ ## Local dry-run (no upload)
70
+
71
+ ```bash
72
+ python -m build
73
+ twine check --strict dist/*
74
+ ```
@@ -0,0 +1,44 @@
1
+ site_name: codexloop
2
+ site_description: Autonomous OpenAI Codex session runner
3
+ site_url: https://adammatthewsteinberger.github.io/codexloop/
4
+ repo_url: https://github.com/adammatthewsteinberger/codexloop
5
+ repo_name: adammatthewsteinberger/codexloop
6
+ theme:
7
+ name: material
8
+ features:
9
+ - navigation.sections
10
+ - content.code.copy
11
+ markdown_extensions:
12
+ - admonition
13
+ - pymdownx.details
14
+ - pymdownx.superfences
15
+ - toc:
16
+ permalink: true
17
+ exclude_docs: |
18
+ plans/**
19
+ superpowers/**
20
+ nav:
21
+ - Home: index.md
22
+ - Getting started: getting-started.md
23
+ - Guides:
24
+ - REST API surface: guides/rest-api-surface.md
25
+ - Architecture:
26
+ - Overview: architecture/index.md
27
+ - ADRs:
28
+ - Index: architecture/adr/index.md
29
+ - "0001 Onion import-linter": architecture/adr/0001-onion-import-linter.md
30
+ - "0002 Subprocess codex exec": architecture/adr/0002-subprocess-codex-exec.md
31
+ - "0003 Credits exhausted": architecture/adr/0003-credits-exhausted.md
32
+ - "0004 Adaptive probe loop": architecture/adr/0004-adaptive-probe-loop.md
33
+ - "0005 Layered capacity probe": architecture/adr/0005-layered-capacity-probe.md
34
+ - "0006 Generated OpenAI REST": architecture/adr/0006-generated-openai-rest.md
35
+ - "0007 Default approval/sandbox": architecture/adr/0007-default-approval-sandbox.md
36
+ - "0008 Policy via -c flags": architecture/adr/0008-policy-via-c-flags.md
37
+ - "0009 Optional app-server": architecture/adr/0009-optional-app-server.md
38
+ - "0010 Rollout best-effort": architecture/adr/0010-rollout-best-effort.md
39
+ - "0011 Never consume resets": architecture/adr/0011-never-consume-resets.md
40
+ - "0012 Minimum Codex version": architecture/adr/0012-minimum-codex-version.md
41
+ - Reference: reference/cli.md
42
+ - Contributing: contributing.md
43
+ - Publishing: publishing.md
44
+ strict: true
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "codexloop"
7
- version = "0.1.0"
7
+ version = "0.2.0"
8
8
  description = "Onion-architected, autonomous OpenAI Codex session runner — never blocks on a human, distinguishes rate limits from exhausted credits, and resumes safely across usage windows."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -1,3 +1,3 @@
1
1
  """codexloop — onion-architected, autonomous OpenAI Codex session runner."""
2
2
 
3
- __version__ = "0.1.0"
3
+ __version__ = "0.2.0"
@@ -148,15 +148,19 @@ class GitSavePointStore:
148
148
  handle.write(json.dumps(entry) + "\n")
149
149
 
150
150
  def _resolve_target(self, points: list[SavePointRef], to: str) -> SavePointRef:
151
+ # Numeric save-point indexes (``1``, ``2``, …) are accepted, but a
152
+ # shortened SHA can be all digits (e.g. ``4158599``). Prefer an exact
153
+ # index hit, then fall through to SHA/ref/label matching.
151
154
  if to.isdigit():
152
155
  n = int(to)
153
156
  for point in points:
154
157
  if point.n == n:
155
158
  return point
156
- raise ValueError(f"no save point numbered {n}")
157
159
  for point in points:
158
160
  if point.ref == to or point.sha.startswith(to) or point.label == to:
159
161
  return point
162
+ if to.isdigit():
163
+ raise ValueError(f"no save point numbered {int(to)}")
160
164
  raise ValueError(f"no save point matching {to!r}")
161
165
 
162
166
  def _is_git_repo(self) -> bool:
@@ -9,6 +9,7 @@ from pathlib import Path
9
9
  import pytest
10
10
  from typer.testing import CliRunner
11
11
 
12
+ from codexloop import __version__
12
13
  from codexloop.application.dto import RunResult
13
14
  from codexloop.cli.app import app
14
15
  from codexloop.domain.control import Stop
@@ -58,7 +59,8 @@ def _plain(text: str) -> str:
58
59
  def test_version_prints_package_version() -> None:
59
60
  result = _invoke("--version")
60
61
  assert result.exit_code == 0
61
- assert "0.1.0" in result.output
62
+ assert __version__ in result.output
63
+ assert result.output.strip() == f"codexloop {__version__}"
62
64
 
63
65
 
64
66
  def test_help_lists_every_command() -> None:
@@ -11,6 +11,7 @@ from pathlib import Path
11
11
  import pytest
12
12
 
13
13
  from codexloop.domain.errors import ConfigurationError
14
+ from codexloop.domain.savepoint import SavePointRef
14
15
  from codexloop.infrastructure.agent import events as events_mod
15
16
  from codexloop.infrastructure.agent.process import _StdoutCollector
16
17
  from codexloop.infrastructure.clock import AnyioSleeper, SystemClock
@@ -179,6 +180,24 @@ def test_git_savepoints_list_unwind_and_errors(tmp_path: Path) -> None:
179
180
  assert store2._staged_paths() == ()
180
181
 
181
182
 
183
+ def test_resolve_target_accepts_all_digit_sha_prefix(tmp_path: Path) -> None:
184
+ """Short SHAs can be decimal-only; do not treat them as save-point indexes."""
185
+ store = GitSavePointStore(cwd=tmp_path, index_path=tmp_path / "idx.jsonl")
186
+ point = SavePointRef(
187
+ n=1,
188
+ ref="refs/codexloop/r1/1",
189
+ sha="41585994ef67172a1b376616357ca2b92f4cb33d",
190
+ label="turn",
191
+ at=datetime.now(UTC),
192
+ plan_item=None,
193
+ committed=True,
194
+ )
195
+ assert store._resolve_target([point], "4158599") is point
196
+ assert store._resolve_target([point], "1") is point
197
+ with pytest.raises(ValueError, match="numbered"):
198
+ store._resolve_target([point], "99")
199
+
200
+
182
201
  def test_git_savepoints_missing_index_file(tmp_path: Path) -> None:
183
202
  store = GitSavePointStore(cwd=tmp_path, index_path=tmp_path / "missing.jsonl")
184
203
  store._index_path.unlink()
@@ -1,3 +0,0 @@
1
- {
2
- ".": "0.1.0"
3
- }
@@ -1,42 +0,0 @@
1
- # Changelog
2
-
3
- ## 0.1.0 (2026-08-13)
4
-
5
-
6
- ### Features
7
-
8
- * add app-server rate-limit probe client ([a30ef93](https://github.com/adammatthewsteinberger/codexloop/commit/a30ef9377685ef9aea8f5096e1759b0f6293574e))
9
- * add application ports and fakes ([33e721d](https://github.com/adammatthewsteinberger/codexloop/commit/33e721d0dab21b38c614ab71ea7c3e47a8126fb3))
10
- * add autonomous runner and run/resume use cases ([bd36f45](https://github.com/adammatthewsteinberger/codexloop/commit/bd36f457548c5969f0fd37453c2d1ab5727d3302))
11
- * add backoff and adaptive wait policy ([43c70c6](https://github.com/adammatthewsteinberger/codexloop/commit/43c70c68396255e10c61907497c53dd0d1c2ba63))
12
- * add bootstrap and core CLI commands ([6b6aafc](https://github.com/adammatthewsteinberger/codexloop/commit/6b6aafc94f8d2513282389f154682b1b5a97bcee))
13
- * add capacity value objects ([1aa3fed](https://github.com/adammatthewsteinberger/codexloop/commit/1aa3fede743d6c5db518f869d03826788c64da5b))
14
- * add clock, logging, config, rundir, state, and lock adapters ([8f7e4ad](https://github.com/adammatthewsteinberger/codexloop/commit/8f7e4ad1aad0f9a754e7ff5777898bfe5a35c5cd))
15
- * add codex argv builder ([42ab842](https://github.com/adammatthewsteinberger/codexloop/commit/42ab8426e676b0c6b59bb655bfc94e4a607338ba))
16
- * add control plane, savepoints, and ops CLI ([512e03f](https://github.com/adammatthewsteinberger/codexloop/commit/512e03f24eddf226425326b992eacc4732f1bc7b))
17
- * add ephemeral read-only exec capacity probe ([427620b](https://github.com/adammatthewsteinberger/codexloop/commit/427620bda645389caf571bcef010d269d3457093))
18
- * add error hierarchy and OpenAI error-code taxonomy ([1bf5aa2](https://github.com/adammatthewsteinberger/codexloop/commit/1bf5aa2f2805c80aeba0f37fbe6da1dcb4a59585))
19
- * add generated OpenAI REST CLI surface with drift gate ([53320f8](https://github.com/adammatthewsteinberger/codexloop/commit/53320f82512869b43075d6eeaf3f6fe73a06a3dd))
20
- * add optional app-server gateway, stream UI, docs, and release scaffolding ([23bfddf](https://github.com/adammatthewsteinberger/codexloop/commit/23bfddfb169cfb37e8fe60a9a80bd7f9b644bba9))
21
- * add plan, budget, session, profile, approval, and control types ([07a8188](https://github.com/adammatthewsteinberger/codexloop/commit/07a8188207fa6fbac5f85114d891b266b6be1bf9))
22
- * add read-only CODEX_HOME rollout tail ([071d6ab](https://github.com/adammatthewsteinberger/codexloop/commit/071d6abe526935893d7d330909e96a308e5203b2))
23
- * add run-loop state machine ([582144f](https://github.com/adammatthewsteinberger/codexloop/commit/582144fcd2b5d3c327f6af36c74307a9a8818966))
24
- * add scripted system harness and test-agent gate ([68a7ebf](https://github.com/adammatthewsteinberger/codexloop/commit/68a7ebf9483013f5e7fae4ff98ff2b0f5da843f0))
25
- * add three-layer completion evaluation ([eee2cc3](https://github.com/adammatthewsteinberger/codexloop/commit/eee2cc3a70562126c438e1a1ba842abca9aa0db6))
26
- * classify turn signals into capacity states ([f7c4162](https://github.com/adammatthewsteinberger/codexloop/commit/f7c4162048b62f83a7b7ea3f99474605f18376ef))
27
- * implement codexloop M1–M5 (onion runner + REST + docs) ([1dbef91](https://github.com/adammatthewsteinberger/codexloop/commit/1dbef9118097d8b8210f6a770df8c4c05956f6ce))
28
- * parse codex exec JSONL events ([1cdc76c](https://github.com/adammatthewsteinberger/codexloop/commit/1cdc76c754f0e0f023f7dc94472be59f9776d3f5))
29
- * supervise codex subprocess with concurrent pumps ([1c95f6e](https://github.com/adammatthewsteinberger/codexloop/commit/1c95f6e6fe628daefe0256e5ba5fb921bfd595a5))
30
- * translate JSONL and drive codex exec gateway ([6a1842c](https://github.com/adammatthewsteinberger/codexloop/commit/6a1842c3bab3b9eb57d052b2bb8f1c45b919b69f))
31
- * wire composite capacity probe and adaptive wait loop ([ab682b1](https://github.com/adammatthewsteinberger/codexloop/commit/ab682b16130829e3ae7a523597213c33509dec22))
32
-
33
-
34
- ### Bug Fixes
35
-
36
- * jitter throttle waits above Retry-After ([666a4e6](https://github.com/adammatthewsteinberger/codexloop/commit/666a4e6c3d73f277946e866d33866091c225e1c8))
37
- * only break session locks for known-dead pids ([712b0f4](https://github.com/adammatthewsteinberger/codexloop/commit/712b0f4a4b25d83ba27c0ca53d8278e6961efbd9))
38
- * preserve remaining work across capacity-rejected turns ([d2d10c3](https://github.com/adammatthewsteinberger/codexloop/commit/d2d10c36a93084a36f48509433d9bb6865172fde))
39
- * seal onion contracts and order drain before signals ([cecf827](https://github.com/adammatthewsteinberger/codexloop/commit/cecf827e841d11df0fb34c71724415970da3ab7d))
40
- * stabilize CI help and process-group cancel tests ([3fe2c6d](https://github.com/adammatthewsteinberger/codexloop/commit/3fe2c6d09f94adb0de528a74364a0d9d177ee77b))
41
- * terminate fatals, apply mid-run controls, harden ops edges ([9171835](https://github.com/adammatthewsteinberger/codexloop/commit/91718359a07f5e25ffd1366c7ea8bbfba51b0a01))
42
- * treat ControlCommand as the inbox union and wrap parse errors ([0885204](https://github.com/adammatthewsteinberger/codexloop/commit/08852040d2a48a14eb5b7b750fa5d02bb9314e4b))
@@ -1,65 +0,0 @@
1
- # Publishing
2
-
3
- `codexloop` ships via [Trusted Publishing](https://docs.pypi.org/trusted-publishers/)
4
- (OIDC). No long-lived PyPI API tokens are stored in GitHub.
5
-
6
- ## Environments
7
-
8
- | GitHub Environment | Index | Workflow |
9
- |---|---|---|
10
- | `testpypi` | https://test.pypi.org | `.github/workflows/publish-testpypi.yml` |
11
- | `pypi` | https://pypi.org | `.github/workflows/release-please.yml` (`publish-pypi`) |
12
-
13
- Create them once (repo **Settings → Environments**), or via API as in the
14
- setup checklist below.
15
-
16
- ## One-time Trusted Publisher setup
17
-
18
- Do this **before** the first upload (pending publisher), signed in as the PyPI
19
- owner account.
20
-
21
- ### TestPyPI
22
-
23
- 1. Open https://test.pypi.org/manage/account/publishing/
24
- 2. Add a pending publisher:
25
- - **PyPI Project Name:** `codexloop`
26
- - **Owner:** `adammatthewsteinberger`
27
- - **Repository name:** `codexloop`
28
- - **Workflow name:** `publish-testpypi.yml`
29
- - **Environment name:** `testpypi`
30
-
31
- ### PyPI
32
-
33
- 1. Open https://pypi.org/manage/account/publishing/
34
- 2. Add a pending publisher:
35
- - **PyPI Project Name:** `codexloop`
36
- - **Owner:** `adammatthewsteinberger`
37
- - **Repository name:** `codexloop`
38
- - **Workflow name:** `release-please.yml`
39
- - **Environment name:** `pypi`
40
-
41
- ## Release flow
42
-
43
- ```text
44
- feat/* ──PR──► develop ──smoke TestPyPI──► main ──release-please──► PyPI
45
- ```
46
-
47
- 1. Land work on `develop` (or merge feature → `main` for the bootstrap release).
48
- 2. Push/`workflow_dispatch` **Publish TestPyPI** to verify the wheel on
49
- TestPyPI (`pip install -i https://test.pypi.org/simple/ --pre codexloop`).
50
- 3. Merge to `main`.
51
- 4. `release-please` opens a release PR from Conventional Commits.
52
- 5. Merge the release PR → GitHub Release + tag → `publish-pypi` uploads to PyPI.
53
-
54
- Manual TestPyPI from `main`:
55
-
56
- ```bash
57
- gh workflow run release-please.yml -f publish_to_testpypi=true
58
- ```
59
-
60
- ## Local dry-run (no upload)
61
-
62
- ```bash
63
- python -m build
64
- twine check --strict dist/*
65
- ```