codex-autorunner 1.0.0__tar.gz → 1.1.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 (441) hide show
  1. codex_autorunner-1.1.0/PKG-INFO +154 -0
  2. codex_autorunner-1.1.0/README.md +90 -0
  3. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/pyproject.toml +6 -1
  4. codex_autorunner-1.1.0/src/codex_autorunner/__init__.py +14 -0
  5. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/codex/harness.py +1 -1
  6. codex_autorunner-1.1.0/src/codex_autorunner/agents/opencode/constants.py +3 -0
  7. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/opencode/harness.py +6 -1
  8. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/opencode/runtime.py +59 -18
  9. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/registry.py +22 -3
  10. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/bootstrap.py +7 -3
  11. codex_autorunner-1.1.0/src/codex_autorunner/cli.py +8 -0
  12. codex_autorunner-1.1.0/src/codex_autorunner/codex_cli.py +20 -0
  13. codex_autorunner-1.1.0/src/codex_autorunner/core/__init__.py +5 -0
  14. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/about_car.py +6 -1
  15. codex_autorunner-1.1.0/src/codex_autorunner/core/app_server_ids.py +59 -0
  16. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/app_server_threads.py +11 -2
  17. codex_autorunner-1.0.0/src/codex_autorunner/integrations/app_server/env.py → codex_autorunner-1.1.0/src/codex_autorunner/core/app_server_utils.py +71 -16
  18. codex_autorunner-1.1.0/src/codex_autorunner/core/archive.py +349 -0
  19. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/codex_runner.py +6 -2
  20. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/config.py +197 -3
  21. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/drafts.py +58 -4
  22. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/engine.py +1329 -680
  23. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/exceptions.py +4 -0
  24. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/flows/controller.py +25 -1
  25. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/flows/models.py +13 -0
  26. codex_autorunner-1.1.0/src/codex_autorunner/core/flows/reasons.py +52 -0
  27. codex_autorunner-1.1.0/src/codex_autorunner/core/flows/reconciler.py +131 -0
  28. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/flows/runtime.py +35 -4
  29. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/flows/store.py +83 -0
  30. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/flows/transition.py +5 -0
  31. codex_autorunner-1.1.0/src/codex_autorunner/core/flows/ux_helpers.py +257 -0
  32. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/git_utils.py +62 -0
  33. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/hub.py +121 -7
  34. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/notifications.py +14 -2
  35. {codex_autorunner-1.0.0/src/codex_autorunner/integrations/agents → codex_autorunner-1.1.0/src/codex_autorunner/core/ports}/__init__.py +6 -5
  36. {codex_autorunner-1.0.0/src/codex_autorunner/integrations/agents → codex_autorunner-1.1.0/src/codex_autorunner/core/ports}/agent_backend.py +11 -3
  37. codex_autorunner-1.1.0/src/codex_autorunner/core/ports/backend_orchestrator.py +41 -0
  38. {codex_autorunner-1.0.0/src/codex_autorunner/integrations/agents → codex_autorunner-1.1.0/src/codex_autorunner/core/ports}/run_event.py +22 -2
  39. codex_autorunner-1.1.0/src/codex_autorunner/core/state_roots.py +57 -0
  40. codex_autorunner-1.1.0/src/codex_autorunner/core/supervisor_protocol.py +15 -0
  41. codex_autorunner-1.1.0/src/codex_autorunner/core/text_delta_coalescer.py +97 -0
  42. codex_autorunner-1.1.0/src/codex_autorunner/core/ticket_linter_cli.py +201 -0
  43. codex_autorunner-1.1.0/src/codex_autorunner/core/ticket_manager_cli.py +432 -0
  44. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/update.py +4 -5
  45. codex_autorunner-1.1.0/src/codex_autorunner/core/update_paths.py +28 -0
  46. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/usage.py +164 -12
  47. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/utils.py +91 -9
  48. codex_autorunner-1.1.0/src/codex_autorunner/flows/review/__init__.py +17 -0
  49. codex_autorunner-1.0.0/src/codex_autorunner/core/review.py → codex_autorunner-1.1.0/src/codex_autorunner/flows/review/service.py +15 -10
  50. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/flows/ticket_flow/definition.py +9 -2
  51. codex_autorunner-1.1.0/src/codex_autorunner/integrations/agents/__init__.py +17 -0
  52. codex_autorunner-1.1.0/src/codex_autorunner/integrations/agents/backend_orchestrator.py +284 -0
  53. codex_autorunner-1.1.0/src/codex_autorunner/integrations/agents/codex_adapter.py +90 -0
  54. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/agents/codex_backend.py +158 -17
  55. codex_autorunner-1.1.0/src/codex_autorunner/integrations/agents/opencode_adapter.py +108 -0
  56. codex_autorunner-1.1.0/src/codex_autorunner/integrations/agents/opencode_backend.py +598 -0
  57. codex_autorunner-1.1.0/src/codex_autorunner/integrations/agents/runner.py +91 -0
  58. codex_autorunner-1.1.0/src/codex_autorunner/integrations/agents/wiring.py +271 -0
  59. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/app_server/client.py +7 -60
  60. codex_autorunner-1.1.0/src/codex_autorunner/integrations/app_server/env.py +5 -0
  61. codex_autorunner-1.0.0/src/codex_autorunner/core/app_server_events.py → codex_autorunner-1.1.0/src/codex_autorunner/integrations/app_server/event_buffer.py +15 -8
  62. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/adapter.py +65 -0
  63. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/config.py +46 -0
  64. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/constants.py +1 -1
  65. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/callbacks.py +7 -0
  66. codex_autorunner-1.1.0/src/codex_autorunner/integrations/telegram/handlers/commands/flows.py +1364 -0
  67. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/commands_runtime.py +4 -3
  68. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/commands_spec.py +8 -2
  69. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/messages.py +1 -0
  70. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/selections.py +61 -1
  71. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/helpers.py +24 -1
  72. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/service.py +15 -10
  73. codex_autorunner-1.1.0/src/codex_autorunner/integrations/telegram/ticket_flow_bridge.py +611 -0
  74. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/transport.py +3 -1
  75. codex_autorunner-1.1.0/src/codex_autorunner/routes/__init__.py +37 -0
  76. codex_autorunner-1.1.0/src/codex_autorunner/routes/agents.py +3 -0
  77. codex_autorunner-1.1.0/src/codex_autorunner/routes/analytics.py +3 -0
  78. codex_autorunner-1.1.0/src/codex_autorunner/routes/app_server.py +3 -0
  79. codex_autorunner-1.1.0/src/codex_autorunner/routes/base.py +3 -0
  80. codex_autorunner-1.1.0/src/codex_autorunner/routes/file_chat.py +7 -0
  81. codex_autorunner-1.1.0/src/codex_autorunner/routes/flows.py +7 -0
  82. codex_autorunner-1.1.0/src/codex_autorunner/routes/messages.py +7 -0
  83. codex_autorunner-1.1.0/src/codex_autorunner/routes/repos.py +3 -0
  84. codex_autorunner-1.1.0/src/codex_autorunner/routes/review.py +3 -0
  85. codex_autorunner-1.1.0/src/codex_autorunner/routes/sessions.py +3 -0
  86. codex_autorunner-1.1.0/src/codex_autorunner/routes/settings.py +3 -0
  87. codex_autorunner-1.1.0/src/codex_autorunner/routes/shared.py +3 -0
  88. codex_autorunner-1.1.0/src/codex_autorunner/routes/system.py +7 -0
  89. codex_autorunner-1.1.0/src/codex_autorunner/routes/usage.py +3 -0
  90. codex_autorunner-1.1.0/src/codex_autorunner/routes/voice.py +3 -0
  91. codex_autorunner-1.1.0/src/codex_autorunner/routes/workspace.py +3 -0
  92. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/server.py +2 -2
  93. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/agentControls.js +40 -11
  94. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/app.js +11 -3
  95. codex_autorunner-1.1.0/src/codex_autorunner/static/archive.js +826 -0
  96. codex_autorunner-1.1.0/src/codex_autorunner/static/archiveApi.js +37 -0
  97. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/autoRefresh.js +7 -7
  98. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/dashboard.js +224 -171
  99. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/hub.js +112 -94
  100. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/index.html +80 -33
  101. codex_autorunner-1.1.0/src/codex_autorunner/static/messages.js +873 -0
  102. codex_autorunner-1.1.0/src/codex_autorunner/static/preserve.js +17 -0
  103. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/settings.js +125 -6
  104. codex_autorunner-1.1.0/src/codex_autorunner/static/smartRefresh.js +52 -0
  105. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/styles.css +1373 -101
  106. codex_autorunner-1.1.0/src/codex_autorunner/static/tabs.js +205 -0
  107. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/terminal.js +18 -0
  108. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/ticketEditor.js +99 -5
  109. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/tickets.js +760 -87
  110. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/utils.js +11 -0
  111. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/workspace.js +133 -40
  112. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/workspaceFileBrowser.js +9 -9
  113. codex_autorunner-1.1.0/src/codex_autorunner/surfaces/__init__.py +5 -0
  114. codex_autorunner-1.1.0/src/codex_autorunner/surfaces/cli/__init__.py +6 -0
  115. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/cli}/cli.py +73 -26
  116. codex_autorunner-1.1.0/src/codex_autorunner/surfaces/cli/codex_cli.py +20 -0
  117. codex_autorunner-1.1.0/src/codex_autorunner/surfaces/telegram/__init__.py +3 -0
  118. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces}/web/app.py +97 -28
  119. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces}/web/hub_jobs.py +2 -2
  120. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces}/web/middleware.py +3 -3
  121. codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web/review.py +6 -0
  122. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/__init__.py +2 -0
  123. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/agents.py +4 -4
  124. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/analytics.py +44 -6
  125. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/app_server.py +4 -4
  126. codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web/routes/archive.py +357 -0
  127. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/base.py +26 -8
  128. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/file_chat.py +7 -7
  129. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/flows.py +291 -107
  130. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/messages.py +6 -6
  131. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/repos.py +3 -3
  132. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/review.py +2 -2
  133. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/sessions.py +2 -2
  134. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/settings.py +2 -2
  135. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/shared.py +8 -4
  136. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/system.py +8 -8
  137. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/usage.py +4 -2
  138. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/voice.py +1 -1
  139. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/workspace.py +11 -11
  140. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces}/web/runner_manager.py +2 -2
  141. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces}/web/schemas.py +40 -0
  142. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces}/web/static_assets.py +48 -2
  143. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces}/web/static_refresh.py +1 -1
  144. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces}/web/terminal_sessions.py +1 -1
  145. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/tickets/__init__.py +8 -1
  146. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/tickets/agent_pool.py +26 -4
  147. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/tickets/files.py +6 -2
  148. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/tickets/models.py +3 -1
  149. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/tickets/outbox.py +12 -0
  150. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/tickets/runner.py +63 -5
  151. codex_autorunner-1.1.0/src/codex_autorunner/web/__init__.py +5 -0
  152. codex_autorunner-1.1.0/src/codex_autorunner/web/app.py +3 -0
  153. codex_autorunner-1.1.0/src/codex_autorunner/web/hub_jobs.py +3 -0
  154. codex_autorunner-1.1.0/src/codex_autorunner/web/middleware.py +3 -0
  155. codex_autorunner-1.1.0/src/codex_autorunner/web/pty_session.py +3 -0
  156. codex_autorunner-1.1.0/src/codex_autorunner/web/runner_manager.py +3 -0
  157. codex_autorunner-1.1.0/src/codex_autorunner/web/schemas.py +3 -0
  158. codex_autorunner-1.1.0/src/codex_autorunner/web/static_assets.py +7 -0
  159. codex_autorunner-1.1.0/src/codex_autorunner/web/static_refresh.py +3 -0
  160. codex_autorunner-1.1.0/src/codex_autorunner/web/terminal_sessions.py +3 -0
  161. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/workspace/paths.py +49 -33
  162. codex_autorunner-1.1.0/src/codex_autorunner.egg-info/PKG-INFO +154 -0
  163. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner.egg-info/SOURCES.txt +76 -6
  164. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_about_car_terminal_context.py +1 -0
  165. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_agent_run_events.py +3 -3
  166. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_agents_registry.py +53 -0
  167. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_api_contract.py +5 -0
  168. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_app_server_events.py +1 -1
  169. codex_autorunner-1.1.0/tests/test_archive_worktree.py +121 -0
  170. codex_autorunner-1.1.0/tests/test_engine_app_server.py +198 -0
  171. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_engine_end_review.py +1 -1
  172. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_hub_create.py +19 -3
  173. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_hub_supervisor.py +25 -4
  174. codex_autorunner-1.1.0/tests/test_opencode_agent_pool.py +120 -0
  175. codex_autorunner-1.1.0/tests/test_opencode_backend_streaming.py +128 -0
  176. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_opencode_runtime.py +33 -0
  177. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_review_service.py +3 -3
  178. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_adapter.py +10 -0
  179. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_bot_config.py +49 -0
  180. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_cache_cleanup.py +10 -0
  181. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_command_registry.py +9 -0
  182. codex_autorunner-1.1.0/tests/test_telegram_flow_aliases.py +75 -0
  183. codex_autorunner-1.1.0/tests/test_telegram_flow_bootstrap.py +172 -0
  184. codex_autorunner-1.1.0/tests/test_telegram_flow_callback_actions.py +167 -0
  185. codex_autorunner-1.1.0/tests/test_telegram_flow_commands.py +22 -0
  186. codex_autorunner-1.1.0/tests/test_telegram_flow_lifecycle.py +206 -0
  187. codex_autorunner-1.1.0/tests/test_telegram_flow_status.py +191 -0
  188. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_handlers_callbacks.py +49 -0
  189. codex_autorunner-1.1.0/tests/test_telegram_ticket_flow_bridge.py +190 -0
  190. codex_autorunner-1.1.0/tests/test_ticket_linter_cli.py +93 -0
  191. codex_autorunner-1.1.0/tests/test_ticket_manager_cli.py +65 -0
  192. codex_autorunner-1.1.0/tests/test_update_paths.py +28 -0
  193. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_usage.py +94 -0
  194. codex_autorunner-1.1.0/tests/test_workspace_paths.py +89 -0
  195. codex_autorunner-1.0.0/PKG-INFO +0 -246
  196. codex_autorunner-1.0.0/README.md +0 -182
  197. codex_autorunner-1.0.0/src/codex_autorunner/__init__.py +0 -3
  198. codex_autorunner-1.0.0/src/codex_autorunner/codex_cli.py +0 -84
  199. codex_autorunner-1.0.0/src/codex_autorunner/core/__init__.py +0 -1
  200. codex_autorunner-1.0.0/src/codex_autorunner/core/static_assets.py +0 -55
  201. codex_autorunner-1.0.0/src/codex_autorunner/core/text_delta_coalescer.py +0 -43
  202. codex_autorunner-1.0.0/src/codex_autorunner/integrations/agents/opencode_backend.py +0 -325
  203. codex_autorunner-1.0.0/src/codex_autorunner/integrations/telegram/handlers/commands/flows.py +0 -227
  204. codex_autorunner-1.0.0/src/codex_autorunner/integrations/telegram/ticket_flow_bridge.py +0 -322
  205. codex_autorunner-1.0.0/src/codex_autorunner/static/messages.js +0 -470
  206. codex_autorunner-1.0.0/src/codex_autorunner/static/tabs.js +0 -64
  207. codex_autorunner-1.0.0/src/codex_autorunner.egg-info/PKG-INFO +0 -246
  208. codex_autorunner-1.0.0/tests/test_engine_app_server.py +0 -161
  209. codex_autorunner-1.0.0/tests/test_workspace_paths.py +0 -42
  210. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/LICENSE +0 -0
  211. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/setup.cfg +0 -0
  212. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/__main__.py +0 -0
  213. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/__init__.py +0 -0
  214. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/base.py +0 -0
  215. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/codex/__init__.py +0 -0
  216. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/opencode/__init__.py +0 -0
  217. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/opencode/agent_config.py +0 -0
  218. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/opencode/client.py +0 -0
  219. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/opencode/events.py +0 -0
  220. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/opencode/logging.py +0 -0
  221. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/opencode/run_prompt.py +0 -0
  222. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/opencode/supervisor.py +0 -0
  223. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/types.py +0 -0
  224. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/api.py +0 -0
  225. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/codex_runner.py +0 -0
  226. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/adapter_utils.py +0 -0
  227. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/app_server_logging.py +0 -0
  228. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/app_server_prompts.py +0 -0
  229. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/circuit_breaker.py +0 -0
  230. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/docs.py +0 -0
  231. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/flows/__init__.py +0 -0
  232. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/flows/definition.py +0 -0
  233. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/flows/worker_process.py +0 -0
  234. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/injected_context.py +0 -0
  235. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/locks.py +0 -0
  236. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/logging_utils.py +0 -0
  237. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/optional_dependencies.py +0 -0
  238. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/patch_utils.py +0 -0
  239. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/path_utils.py +0 -0
  240. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/prompt.py +0 -0
  241. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/prompts.py +0 -0
  242. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/redaction.py +0 -0
  243. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/request_context.py +0 -0
  244. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/retry.py +0 -0
  245. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/review_context.py +0 -0
  246. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/run_index.py +0 -0
  247. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/runner_controller.py +0 -0
  248. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/runner_process.py +0 -0
  249. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/sqlite_utils.py +0 -0
  250. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/state.py +0 -0
  251. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/supervisor_utils.py +0 -0
  252. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/update_runner.py +0 -0
  253. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/discovery.py +0 -0
  254. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/flows/ticket_flow/__init__.py +0 -0
  255. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/housekeeping.py +0 -0
  256. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/__init__.py +0 -0
  257. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/app_server/__init__.py +0 -0
  258. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/app_server/supervisor.py +0 -0
  259. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/github/__init__.py +0 -0
  260. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/github/service.py +0 -0
  261. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/__init__.py +0 -0
  262. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/api_schemas.py +0 -0
  263. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/commands_registry.py +0 -0
  264. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/dispatch.py +0 -0
  265. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/doctor.py +0 -0
  266. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/__init__.py +0 -0
  267. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/approvals.py +0 -0
  268. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/commands/__init__.py +0 -0
  269. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/commands/approvals.py +0 -0
  270. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/commands/execution.py +0 -0
  271. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/commands/files.py +0 -0
  272. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/commands/formatting.py +0 -0
  273. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/commands/github.py +0 -0
  274. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/commands/shared.py +0 -0
  275. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/commands/voice.py +0 -0
  276. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/commands/workspace.py +0 -0
  277. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/questions.py +0 -0
  278. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/utils.py +0 -0
  279. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/notifications.py +0 -0
  280. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/outbox.py +0 -0
  281. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/overflow.py +0 -0
  282. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/progress_stream.py +0 -0
  283. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/rendering.py +0 -0
  284. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/retry.py +0 -0
  285. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/runtime.py +0 -0
  286. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/state.py +0 -0
  287. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/trigger_mode.py +0 -0
  288. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/types.py +0 -0
  289. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/voice.py +0 -0
  290. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/manifest.py +0 -0
  291. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/plugin_api.py +0 -0
  292. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/agentEvents.js +0 -0
  293. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/bootstrap.js +0 -0
  294. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/bus.js +0 -0
  295. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/cache.js +0 -0
  296. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/constants.js +0 -0
  297. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/diffRenderer.js +0 -0
  298. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/docChatCore.js +0 -0
  299. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/docChatStorage.js +0 -0
  300. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/docChatVoice.js +0 -0
  301. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/docEditor.js +0 -0
  302. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/env.js +0 -0
  303. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/eventSummarizer.js +0 -0
  304. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/fileChat.js +0 -0
  305. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/health.js +0 -0
  306. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/liveUpdates.js +0 -0
  307. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/loader.js +0 -0
  308. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/mobileCompact.js +0 -0
  309. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/terminalManager.js +0 -0
  310. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/ticketChatActions.js +0 -0
  311. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/ticketChatEvents.js +0 -0
  312. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/ticketChatStorage.js +0 -0
  313. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/ticketChatStream.js +0 -0
  314. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/ticketVoice.js +0 -0
  315. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/LICENSE.xterm +0 -0
  316. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-400-cyrillic-ext.woff2 +0 -0
  317. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-400-cyrillic.woff2 +0 -0
  318. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-400-greek.woff2 +0 -0
  319. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-400-latin-ext.woff2 +0 -0
  320. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-400-latin.woff2 +0 -0
  321. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-400-vietnamese.woff2 +0 -0
  322. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-500-cyrillic-ext.woff2 +0 -0
  323. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-500-cyrillic.woff2 +0 -0
  324. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-500-greek.woff2 +0 -0
  325. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-500-latin-ext.woff2 +0 -0
  326. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-500-latin.woff2 +0 -0
  327. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-500-vietnamese.woff2 +0 -0
  328. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-600-cyrillic-ext.woff2 +0 -0
  329. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-600-cyrillic.woff2 +0 -0
  330. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-600-greek.woff2 +0 -0
  331. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-600-latin-ext.woff2 +0 -0
  332. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-600-latin.woff2 +0 -0
  333. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-600-vietnamese.woff2 +0 -0
  334. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/OFL.txt +0 -0
  335. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/xterm-addon-fit.js +0 -0
  336. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/xterm.css +0 -0
  337. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/xterm.js +0 -0
  338. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/voice.js +0 -0
  339. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/workspaceApi.js +0 -0
  340. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces}/web/__init__.py +0 -0
  341. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces}/web/pty_session.py +0 -0
  342. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/terminal_images.py +0 -0
  343. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/tickets/frontmatter.py +0 -0
  344. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/tickets/lint.py +0 -0
  345. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/tickets/replies.py +0 -0
  346. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/tickets/spec_ingest.py +0 -0
  347. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/voice/__init__.py +0 -0
  348. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/voice/capture.py +0 -0
  349. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/voice/config.py +0 -0
  350. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/voice/provider.py +0 -0
  351. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/voice/providers/__init__.py +0 -0
  352. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/voice/providers/openai_whisper.py +0 -0
  353. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/voice/resolver.py +0 -0
  354. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/voice/service.py +0 -0
  355. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/workspace/__init__.py +0 -0
  356. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner.egg-info/dependency_links.txt +0 -0
  357. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner.egg-info/entry_points.txt +0 -0
  358. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner.egg-info/requires.txt +0 -0
  359. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner.egg-info/top_level.txt +0 -0
  360. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_agents_plugins.py +0 -0
  361. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_app_server_client.py +0 -0
  362. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_app_server_event_formatter.py +0 -0
  363. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_app_server_prompts.py +0 -0
  364. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_app_server_supervisor.py +0 -0
  365. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_app_server_thread_registry.py +0 -0
  366. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_auth_middleware.py +0 -0
  367. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_base_path.py +0 -0
  368. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_base_path_static.py +0 -0
  369. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_cli_init.py +0 -0
  370. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_cli_sessions.py +0 -0
  371. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_cli_status.py +0 -0
  372. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_codex_app_server_integration.py +0 -0
  373. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_codex_cli_flags.py +0 -0
  374. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_codex_runner.py +0 -0
  375. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_config_resolution.py +0 -0
  376. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_core_web_boundary.py +0 -0
  377. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_engine_logs.py +0 -0
  378. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_file_chat_drafts.py +0 -0
  379. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_housekeeping.py +0 -0
  380. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_hub_foundation.py +0 -0
  381. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_hub_terminal_sessions.py +0 -0
  382. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_hub_ui_escape.py +0 -0
  383. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_lock_utils.py +0 -0
  384. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_logging_utils.py +0 -0
  385. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_notifications.py +0 -0
  386. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_opencode_agent_config.py +0 -0
  387. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_opencode_client.py +0 -0
  388. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_opencode_event_formatter.py +0 -0
  389. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_opencode_integration.py +0 -0
  390. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_opencode_review_arguments.py +0 -0
  391. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_optional_dependencies.py +0 -0
  392. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_origin_middleware.py +0 -0
  393. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_patch_utils.py +0 -0
  394. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_prompt.py +0 -0
  395. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_redaction.py +0 -0
  396. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_request_logging.py +0 -0
  397. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_review_context.py +0 -0
  398. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_runner_controller.py +0 -0
  399. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_sse_streams.py +0 -0
  400. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_state_lock.py +0 -0
  401. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_state_sessions.py +0 -0
  402. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_static.py +0 -0
  403. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_static_asset_cache.py +0 -0
  404. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_system_update_check.py +0 -0
  405. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_system_update_worker.py +0 -0
  406. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_bot_integration.py +0 -0
  407. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_bot_lock.py +0 -0
  408. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_codex_feature_flags.py +0 -0
  409. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_fast_ack.py +0 -0
  410. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_handlers_messages.py +0 -0
  411. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_interrupt_status.py +0 -0
  412. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_media_batch_failure.py +0 -0
  413. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_opencode_context_cache.py +0 -0
  414. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_opencode_usage.py +0 -0
  415. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_outbox.py +0 -0
  416. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_overflow.py +0 -0
  417. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_paths_compatible.py +0 -0
  418. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_progress_stream.py +0 -0
  419. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_review_opencode.py +0 -0
  420. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_state.py +0 -0
  421. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_status_rate_limits.py +0 -0
  422. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_task_tracking.py +0 -0
  423. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_thread_paths.py +0 -0
  424. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_topic_queue.py +0 -0
  425. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_transport.py +0 -0
  426. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_trigger_mode.py +0 -0
  427. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_turn_queue.py +0 -0
  428. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_update_dedupe.py +0 -0
  429. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_whisper_disclaimer.py +0 -0
  430. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_terminal_idle_timeout.py +0 -0
  431. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_terminal_input_dedupe.py +0 -0
  432. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_ticket_flow_approval_config.py +0 -0
  433. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_voice_capture.py +0 -0
  434. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_voice_config.py +0 -0
  435. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_voice_service.py +0 -0
  436. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_voice_transcribe_endpoint.py +0 -0
  437. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_voice_ui.py +0 -0
  438. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_voice_whisper_mime_types.py +0 -0
  439. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_voice_whisper_provider.py +0 -0
  440. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_workspace_functional.py +0 -0
  441. {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_workspace_helpers.py +0 -0
@@ -0,0 +1,154 @@
1
+ Metadata-Version: 2.4
2
+ Name: codex-autorunner
3
+ Version: 1.1.0
4
+ Summary: Codex autorunner CLI per DESIGN-V1
5
+ Author: Codex
6
+ License: MIT License
7
+
8
+ Copyright (c) 2025 David Zhang
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://github.com/Git-on-my-level/codex-autorunner
29
+ Project-URL: Repository, https://github.com/Git-on-my-level/codex-autorunner
30
+ Project-URL: Issues, https://github.com/Git-on-my-level/codex-autorunner/issues
31
+ Keywords: codex,automation,agent,cli,fastapi
32
+ Classifier: License :: OSI Approved :: MIT License
33
+ Classifier: Programming Language :: Python :: 3
34
+ Classifier: Programming Language :: Python :: 3 :: Only
35
+ Classifier: Operating System :: OS Independent
36
+ Requires-Python: >=3.9
37
+ Description-Content-Type: text/markdown
38
+ License-File: LICENSE
39
+ Requires-Dist: typer>=0.9
40
+ Requires-Dist: click<8.2
41
+ Requires-Dist: pyyaml>=6.0
42
+ Requires-Dist: fastapi>=0.111
43
+ Requires-Dist: uvicorn[standard]>=0.30
44
+ Requires-Dist: ptyprocess>=0.7
45
+ Requires-Dist: python-multipart>=0.0.9
46
+ Requires-Dist: python-dotenv>=1.0
47
+ Requires-Dist: httpx>=0.27
48
+ Requires-Dist: tenacity>=8.0
49
+ Provides-Extra: dev
50
+ Requires-Dist: black==25.11.0; extra == "dev"
51
+ Requires-Dist: mypy>=1.10; extra == "dev"
52
+ Requires-Dist: pytest>=7.0; extra == "dev"
53
+ Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
54
+ Requires-Dist: pytest-timeout>=2.0; extra == "dev"
55
+ Requires-Dist: ruff>=0.5.0; extra == "dev"
56
+ Requires-Dist: types-PyYAML; extra == "dev"
57
+ Provides-Extra: telegram
58
+ Requires-Dist: httpx>=0.27; extra == "telegram"
59
+ Provides-Extra: voice
60
+ Requires-Dist: httpx>=0.27; extra == "voice"
61
+ Requires-Dist: python-multipart>=0.0.9; extra == "voice"
62
+ Provides-Extra: github
63
+ Dynamic: license-file
64
+
65
+ # CAR (codex-autorunner)
66
+ [![PyPI](https://img.shields.io/pypi/v/codex-autorunner.svg)](https://pypi.org/project/codex-autorunner/)
67
+
68
+ CAR provides a set of low-opinion agent coordination tools for you to run long complex implementations using the agents you already love.
69
+
70
+ What this looks like in practice:
71
+ - You write a plan, or generate a plan by chatting with your favorite AI
72
+ - You convert the plan (or ask an AI to convert it for you) into CAR compatible tickets (markdown with some frontmatter)
73
+ - Go off and do something else, no need to babysit the agents, they will notify you if they need your input
74
+
75
+ ![CAR Web Hub Screenshot](docs/screenshots/hub.png)
76
+
77
+ ## How it works
78
+ CAR is very simple. At it's core, CAR is a state machine which checks to see if there are any incomplete tickets. If yes, pick the next one and run it against an agent. Tickets can be pre-populated by the user, but agents can also write tickets. _Tickets are the control plane for CAR_.
79
+
80
+ When each agent wakes up, it gets knowledge about CAR and how to operate within CAR, a pre-defined set of context (workspace files), the current ticket, and optionally the final output of the previous agent. This simple loop ensures that agents know enough to use CAR while also focusing them on the task at hand.
81
+
82
+ ## Philosophy
83
+ The philosophy behind CAR is to let the agents do what they do best, and get out of their way. CAR is _very bitter-lesson-pilled_. As models and agents get more powerful, CAR should serve as a form of leverage, and avoid constraining models and their harnesses. This is why we treat the filesystem as the first class data plane and utilize tools and languages the models are already very familiar with (git, python).
84
+
85
+ CAR treats tickets as the control plane and models as the execution layer. This means that we rely on agents to follow the instructions written in the tickets. If you use a sufficiently weak model, CAR may not work well for you. CAR is an amplifier for agent capabilities. Agents who like to scope creep (create too many new tickets) or reward hack (mark a ticket as done despite it being incomplete) are not a good fit for CAR.
86
+
87
+ ## Interaction patterns
88
+ CAR's core is a set of python functions surfaced as a CLI, operating on a file system. There are current 2 UIs built on top of this core.
89
+
90
+ ### Web UI
91
+ The web UI is the main control plane for CAR. From here you can set up new repositories or clone existing ones, chat with agents using their TUI, and run the ticket autorunner. There are many quality-of-life features like Whisper integration, editing documents by chatting with AI (useful for mobile), viewing usage analytics, and much more. The Web UI is the most full featured user-facing interface and a good starting point for trying out CAR.
92
+
93
+ I recommend serving the web UI over Tailscale. There is an auth token option but the system is not very battle tested.
94
+
95
+ ### Telegram
96
+ Telegram is the "on-the-go" and notification hub for CAR. From here you can kick off and monitor existing tickets, set up new tickets, and chat with agents. Your primary UX here is asking the agent to do things for you rather than you doing it yourself like you would on the web UI. This is great for on-the-go work, but it doesn't have full feature parity with the web UI.
97
+
98
+ ## Quickstart
99
+
100
+ The fastest way to get started is to pass [this setup guide](docs/AGENT_SETUP_GUIDE.md) to your favorite AI agent. The agent will walk you through installation and configuration interactively based on your environment.
101
+
102
+ **TL;DR for the impatient:**
103
+
104
+ # Install
105
+ ```
106
+ pipx install codex-autorunner
107
+ ```
108
+ # Initialize in your repo
109
+ ```
110
+ cd /path/to/your/repo
111
+ car init
112
+ ```
113
+ # Verify setup
114
+ ```
115
+ car doctor
116
+ ```
117
+ # Create a ticket and run
118
+ ```
119
+ car run
120
+ ```
121
+
122
+ ## Supported models
123
+ CAR currently supports:
124
+ - Codex
125
+ - Opencode
126
+
127
+ CAR is built to easily integrate any reasonable agent built for Agent Client Protocol (ACP). If you would like to see your agent supported, please reach out or open a PR.
128
+
129
+ ## Examples
130
+ Build out complex features and products by providing a series of tickets assigned to various agents.
131
+ ![CAR Tickets in Progress Screenshot](docs/screenshots/tickets-in-progress.png)
132
+
133
+ Tickets are just markdown files that both you and the agent can edit.
134
+ ![CAR Ticket Markdown Screenshot](docs/screenshots/ticket-markdown.png)
135
+
136
+ You don't have to babysit the agents, they inbox you or ping you on Telegram.
137
+ ![CAR Inbox Screenshot](docs/screenshots/inbox.png)
138
+
139
+ You can collaborate with the agents in a shared workspace, independent of the codebase. Drop context there, extract artifacts, it's like a shared scratchpad.
140
+ ![CAR Workspace Screenshot](docs/screenshots/workspace.png)
141
+
142
+ All core workspace documents are also just markdown files, so you and the agent can easily edit them.
143
+ ![CAR Workspace New MD Screenshot](docs/screenshots/workspace-new-md.png)
144
+
145
+ If you need to do something more custom or granular, you can use your favorite agent TUIs in the built-in terminal.
146
+ ![CAR Terminal Codex Screenshot](docs/screenshots/terminal-codex.png)
147
+ ![CAR Terminal Opencode Screenshot](docs/screenshots/terminal-opencode.png)
148
+
149
+ On the go? The web UI is mobile responsive, or if you prefer you can type or voice chat with your agents on Telegram.
150
+ ![CAR Telegram Media Voice Screenshot](docs/screenshots/telegram-media-voice.PNG)
151
+ ![CAR Telegram Media Image Screenshot](docs/screenshots/telegram-media-image.PNG)
152
+
153
+ ## Star history
154
+ [![Star History Chart](https://api.star-history.com/svg?repos=Git-on-my-level/codex-autorunner&type=Date)](https://star-history.com/#Git-on-my-level/codex-autorunner&Date)
@@ -0,0 +1,90 @@
1
+ # CAR (codex-autorunner)
2
+ [![PyPI](https://img.shields.io/pypi/v/codex-autorunner.svg)](https://pypi.org/project/codex-autorunner/)
3
+
4
+ CAR provides a set of low-opinion agent coordination tools for you to run long complex implementations using the agents you already love.
5
+
6
+ What this looks like in practice:
7
+ - You write a plan, or generate a plan by chatting with your favorite AI
8
+ - You convert the plan (or ask an AI to convert it for you) into CAR compatible tickets (markdown with some frontmatter)
9
+ - Go off and do something else, no need to babysit the agents, they will notify you if they need your input
10
+
11
+ ![CAR Web Hub Screenshot](docs/screenshots/hub.png)
12
+
13
+ ## How it works
14
+ CAR is very simple. At it's core, CAR is a state machine which checks to see if there are any incomplete tickets. If yes, pick the next one and run it against an agent. Tickets can be pre-populated by the user, but agents can also write tickets. _Tickets are the control plane for CAR_.
15
+
16
+ When each agent wakes up, it gets knowledge about CAR and how to operate within CAR, a pre-defined set of context (workspace files), the current ticket, and optionally the final output of the previous agent. This simple loop ensures that agents know enough to use CAR while also focusing them on the task at hand.
17
+
18
+ ## Philosophy
19
+ The philosophy behind CAR is to let the agents do what they do best, and get out of their way. CAR is _very bitter-lesson-pilled_. As models and agents get more powerful, CAR should serve as a form of leverage, and avoid constraining models and their harnesses. This is why we treat the filesystem as the first class data plane and utilize tools and languages the models are already very familiar with (git, python).
20
+
21
+ CAR treats tickets as the control plane and models as the execution layer. This means that we rely on agents to follow the instructions written in the tickets. If you use a sufficiently weak model, CAR may not work well for you. CAR is an amplifier for agent capabilities. Agents who like to scope creep (create too many new tickets) or reward hack (mark a ticket as done despite it being incomplete) are not a good fit for CAR.
22
+
23
+ ## Interaction patterns
24
+ CAR's core is a set of python functions surfaced as a CLI, operating on a file system. There are current 2 UIs built on top of this core.
25
+
26
+ ### Web UI
27
+ The web UI is the main control plane for CAR. From here you can set up new repositories or clone existing ones, chat with agents using their TUI, and run the ticket autorunner. There are many quality-of-life features like Whisper integration, editing documents by chatting with AI (useful for mobile), viewing usage analytics, and much more. The Web UI is the most full featured user-facing interface and a good starting point for trying out CAR.
28
+
29
+ I recommend serving the web UI over Tailscale. There is an auth token option but the system is not very battle tested.
30
+
31
+ ### Telegram
32
+ Telegram is the "on-the-go" and notification hub for CAR. From here you can kick off and monitor existing tickets, set up new tickets, and chat with agents. Your primary UX here is asking the agent to do things for you rather than you doing it yourself like you would on the web UI. This is great for on-the-go work, but it doesn't have full feature parity with the web UI.
33
+
34
+ ## Quickstart
35
+
36
+ The fastest way to get started is to pass [this setup guide](docs/AGENT_SETUP_GUIDE.md) to your favorite AI agent. The agent will walk you through installation and configuration interactively based on your environment.
37
+
38
+ **TL;DR for the impatient:**
39
+
40
+ # Install
41
+ ```
42
+ pipx install codex-autorunner
43
+ ```
44
+ # Initialize in your repo
45
+ ```
46
+ cd /path/to/your/repo
47
+ car init
48
+ ```
49
+ # Verify setup
50
+ ```
51
+ car doctor
52
+ ```
53
+ # Create a ticket and run
54
+ ```
55
+ car run
56
+ ```
57
+
58
+ ## Supported models
59
+ CAR currently supports:
60
+ - Codex
61
+ - Opencode
62
+
63
+ CAR is built to easily integrate any reasonable agent built for Agent Client Protocol (ACP). If you would like to see your agent supported, please reach out or open a PR.
64
+
65
+ ## Examples
66
+ Build out complex features and products by providing a series of tickets assigned to various agents.
67
+ ![CAR Tickets in Progress Screenshot](docs/screenshots/tickets-in-progress.png)
68
+
69
+ Tickets are just markdown files that both you and the agent can edit.
70
+ ![CAR Ticket Markdown Screenshot](docs/screenshots/ticket-markdown.png)
71
+
72
+ You don't have to babysit the agents, they inbox you or ping you on Telegram.
73
+ ![CAR Inbox Screenshot](docs/screenshots/inbox.png)
74
+
75
+ You can collaborate with the agents in a shared workspace, independent of the codebase. Drop context there, extract artifacts, it's like a shared scratchpad.
76
+ ![CAR Workspace Screenshot](docs/screenshots/workspace.png)
77
+
78
+ All core workspace documents are also just markdown files, so you and the agent can easily edit them.
79
+ ![CAR Workspace New MD Screenshot](docs/screenshots/workspace-new-md.png)
80
+
81
+ If you need to do something more custom or granular, you can use your favorite agent TUIs in the built-in terminal.
82
+ ![CAR Terminal Codex Screenshot](docs/screenshots/terminal-codex.png)
83
+ ![CAR Terminal Opencode Screenshot](docs/screenshots/terminal-opencode.png)
84
+
85
+ On the go? The web UI is mobile responsive, or if you prefer you can type or voice chat with your agents on Telegram.
86
+ ![CAR Telegram Media Voice Screenshot](docs/screenshots/telegram-media-voice.PNG)
87
+ ![CAR Telegram Media Image Screenshot](docs/screenshots/telegram-media-image.PNG)
88
+
89
+ ## Star history
90
+ [![Star History Chart](https://api.star-history.com/svg?repos=Git-on-my-level/codex-autorunner&type=Date)](https://star-history.com/#Git-on-my-level/codex-autorunner&Date)
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "codex-autorunner"
3
- version = "1.0.0"
3
+ version = "1.1.0"
4
4
  description = "Codex autorunner CLI per DESIGN-V1"
5
5
  readme = "README.md"
6
6
  license = {file = "LICENSE"}
@@ -82,6 +82,7 @@ completions = true
82
82
  cache_dir = ".codex-autorunner/pytest-cache"
83
83
  asyncio_mode = "auto"
84
84
  asyncio_default_fixture_loop_scope = "function"
85
+ norecursedirs = ["worktrees", ".git", ".venv", ".codex-autorunner"]
85
86
  markers = [
86
87
  "integration: marks tests as integration tests that require external dependencies (deselect with '-m \"not integration\"')",
87
88
  "timeout(seconds): per-test timeout (provided by pytest-timeout)",
@@ -95,6 +96,7 @@ filterwarnings = [
95
96
  [tool.ruff]
96
97
  line-length = 88
97
98
  target-version = "py39"
99
+ src = ["src"]
98
100
 
99
101
  [tool.ruff.lint]
100
102
  select = ["E", "F", "W", "I", "B"]
@@ -105,8 +107,11 @@ ignore = ["E501"]
105
107
  "src/codex_autorunner/pty_session.py" = ["F403"]
106
108
  "src/codex_autorunner/static_assets.py" = ["F403"]
107
109
  "src/codex_autorunner/cli.py" = ["B008"]
110
+ "src/codex_autorunner/surfaces/cli/cli.py" = ["B008"]
108
111
  "src/codex_autorunner/routes/terminal_images.py" = ["B008"]
112
+ "src/codex_autorunner/surfaces/web/routes/terminal_images.py" = ["B008"]
109
113
  "src/codex_autorunner/routes/voice.py" = ["B008"]
114
+ "src/codex_autorunner/surfaces/web/routes/voice.py" = ["B008"]
110
115
 
111
116
  [tool.mypy]
112
117
  python_version = "3.9"
@@ -0,0 +1,14 @@
1
+ """Codex autorunner package."""
2
+
3
+ __all__ = [
4
+ "cli",
5
+ "core",
6
+ "integrations",
7
+ "routes",
8
+ "server",
9
+ "surfaces",
10
+ "surfaces.web.routes",
11
+ "surfaces.web",
12
+ "voice",
13
+ "web",
14
+ ]
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  from pathlib import Path
4
4
  from typing import Any, AsyncIterator, Optional
5
5
 
6
- from ...core.app_server_events import AppServerEventBuffer
6
+ from ...integrations.app_server.event_buffer import AppServerEventBuffer
7
7
  from ...integrations.app_server.supervisor import WorkspaceAppServerSupervisor
8
8
  from ..base import AgentHarness
9
9
  from ..types import AgentId, ConversationRef, ModelCatalog, ModelSpec, TurnRef
@@ -0,0 +1,3 @@
1
+ DEFAULT_TICKET_MODEL = "zai-coding-plan/glm-4.7"
2
+
3
+ __all__ = ["DEFAULT_TICKET_MODEL"]
@@ -6,9 +6,10 @@ import logging
6
6
  from pathlib import Path
7
7
  from typing import Any, AsyncIterator, Optional
8
8
 
9
- from ...core.app_server_events import format_sse
9
+ from ...integrations.app_server.event_buffer import format_sse
10
10
  from ..base import AgentHarness
11
11
  from ..types import AgentId, ConversationRef, ModelCatalog, ModelSpec, TurnRef
12
+ from .constants import DEFAULT_TICKET_MODEL
12
13
  from .runtime import (
13
14
  build_turn_id,
14
15
  extract_session_id,
@@ -168,6 +169,8 @@ class OpenCodeHarness(AgentHarness):
168
169
  sandbox_policy: Optional[Any],
169
170
  ) -> TurnRef:
170
171
  client = await self._supervisor.get_client(workspace_root)
172
+ if model is None:
173
+ model = DEFAULT_TICKET_MODEL
171
174
  model_payload = split_model_id(model)
172
175
  await client.prompt_async(
173
176
  conversation_id,
@@ -192,6 +195,8 @@ class OpenCodeHarness(AgentHarness):
192
195
  sandbox_policy: Optional[Any],
193
196
  ) -> TurnRef:
194
197
  client = await self._supervisor.get_client(workspace_root)
198
+ if model is None:
199
+ model = DEFAULT_TICKET_MODEL
195
200
  arguments = prompt if prompt else ""
196
201
 
197
202
  async def _send_review() -> None:
@@ -122,6 +122,12 @@ def extract_session_id(
122
122
  value = payload.get(key)
123
123
  if isinstance(value, str) and value:
124
124
  return value
125
+ info = payload.get("info")
126
+ if isinstance(info, dict):
127
+ for key in ("sessionID", "sessionId", "session_id"):
128
+ value = info.get(key)
129
+ if isinstance(value, str) and value:
130
+ return value
125
131
  if allow_fallback_id:
126
132
  value = payload.get("id")
127
133
  if isinstance(value, str) and value:
@@ -132,6 +138,12 @@ def extract_session_id(
132
138
  value = properties.get(key)
133
139
  if isinstance(value, str) and value:
134
140
  return value
141
+ info = properties.get("info")
142
+ if isinstance(info, dict):
143
+ for key in ("sessionID", "sessionId", "session_id"):
144
+ value = info.get(key)
145
+ if isinstance(value, str) and value:
146
+ return value
135
147
  part = properties.get("part")
136
148
  if isinstance(part, dict):
137
149
  for key in ("sessionID", "sessionId", "session_id"):
@@ -757,8 +769,9 @@ async def collect_opencode_output_from_events(
757
769
  error: Optional[str] = None
758
770
  message_roles: dict[str, str] = {}
759
771
  message_roles_seen = False
760
- last_role_seen: Optional[str] = None
761
772
  pending_text: dict[str, list[str]] = {}
773
+ pending_no_id: list[str] = []
774
+ no_id_role: Optional[str] = None
762
775
  fallback_message: Optional[tuple[Optional[str], Optional[str], str]] = None
763
776
  last_usage_total: Optional[int] = None
764
777
  last_context_window: Optional[int] = None
@@ -793,7 +806,7 @@ async def collect_opencode_output_from_events(
793
806
  return None
794
807
 
795
808
  def _register_message_role(payload: Any) -> tuple[Optional[str], Optional[str]]:
796
- nonlocal last_role_seen, message_roles_seen
809
+ nonlocal message_roles_seen
797
810
  if not isinstance(payload, dict):
798
811
  return None, None
799
812
  info = payload.get("info")
@@ -806,18 +819,27 @@ async def collect_opencode_output_from_events(
806
819
  if isinstance(role, str) and msg_id:
807
820
  message_roles[msg_id] = role
808
821
  message_roles_seen = True
809
- last_role_seen = role
810
822
  return msg_id, role if isinstance(role, str) else None
811
823
 
824
+ def _flush_pending_no_id_as_assistant() -> None:
825
+ nonlocal no_id_role
826
+ if pending_no_id:
827
+ text_parts.extend(pending_no_id)
828
+ pending_no_id.clear()
829
+ no_id_role = "assistant"
830
+
831
+ def _discard_pending_no_id() -> None:
832
+ if pending_no_id:
833
+ pending_no_id.clear()
834
+
812
835
  def _append_text_for_message(message_id: Optional[str], text: str) -> None:
813
836
  if not text:
814
837
  return
815
838
  if message_id is None:
816
- if not message_roles_seen:
817
- text_parts.append(text)
818
- return
819
- if last_role_seen != "user":
839
+ if no_id_role == "assistant":
820
840
  text_parts.append(text)
841
+ else:
842
+ pending_no_id.append(text)
821
843
  return
822
844
  role = message_roles.get(message_id)
823
845
  if role == "user":
@@ -839,12 +861,32 @@ async def collect_opencode_output_from_events(
839
861
  text_parts.extend(pending)
840
862
 
841
863
  def _flush_all_pending_text() -> None:
842
- if not pending_text:
864
+ if pending_text:
865
+ for pending in list(pending_text.values()):
866
+ if pending:
867
+ text_parts.extend(pending)
868
+ pending_text.clear()
869
+ if pending_no_id:
870
+ # If we have not seen a role yet, assume assistant for backwards
871
+ # compatibility with providers that omit roles entirely. Otherwise,
872
+ # only flush when we have already classified no-id text as assistant
873
+ # or when we have no other text (to avoid echoing user prompts).
874
+ if not message_roles_seen or no_id_role == "assistant" or not text_parts:
875
+ text_parts.extend(pending_no_id)
876
+ pending_no_id.clear()
877
+
878
+ def _handle_role_update(message_id: Optional[str], role: Optional[str]) -> None:
879
+ nonlocal no_id_role
880
+ if not role:
881
+ return
882
+ if role == "assistant":
883
+ _flush_pending_text(message_id)
884
+ _flush_pending_no_id_as_assistant()
843
885
  return
844
- for pending in list(pending_text.values()):
845
- if pending:
846
- text_parts.extend(pending)
847
- pending_text.clear()
886
+ if role == "user":
887
+ _flush_pending_text(message_id)
888
+ _discard_pending_no_id()
889
+ no_id_role = None
848
890
 
849
891
  async def _resolve_session_model_ids() -> tuple[Optional[str], Optional[str]]:
850
892
  nonlocal session_model_ids
@@ -1002,7 +1044,7 @@ async def collect_opencode_output_from_events(
1002
1044
  status_type=status_type,
1003
1045
  idle_seconds=idle_seconds,
1004
1046
  )
1005
- if not text_parts and pending_text:
1047
+ if not text_parts and (pending_text or pending_no_id):
1006
1048
  _flush_all_pending_text()
1007
1049
  break
1008
1050
  if last_primary_completion_at is not None:
@@ -1079,7 +1121,7 @@ async def collect_opencode_output_from_events(
1079
1121
  status_type=status_type,
1080
1122
  idle_seconds=idle_seconds,
1081
1123
  )
1082
- if not text_parts and pending_text:
1124
+ if not text_parts and (pending_text or pending_no_id):
1083
1125
  _flush_all_pending_text()
1084
1126
  break
1085
1127
  if last_primary_completion_at is not None:
@@ -1296,8 +1338,7 @@ async def collect_opencode_output_from_events(
1296
1338
  if event.event in ("message.updated", "message.completed"):
1297
1339
  if is_primary_session:
1298
1340
  msg_id, role = _register_message_role(payload)
1299
- if role == "assistant":
1300
- _flush_pending_text(msg_id)
1341
+ _handle_role_update(msg_id, role)
1301
1342
  if event.event == "message.part.updated":
1302
1343
  properties = (
1303
1344
  payload.get("properties") if isinstance(payload, dict) else None
@@ -1470,7 +1511,7 @@ async def collect_opencode_output_from_events(
1470
1511
  ):
1471
1512
  if not is_primary_session:
1472
1513
  continue
1473
- if not text_parts and pending_text:
1514
+ if not text_parts and (pending_text or pending_no_id):
1474
1515
  _flush_all_pending_text()
1475
1516
  break
1476
1517
  if event.event == "message.completed" and is_primary_session:
@@ -1485,7 +1526,7 @@ async def collect_opencode_output_from_events(
1485
1526
  resolved_role = message_roles.get(msg_id)
1486
1527
  if resolved_role == "assistant":
1487
1528
  _append_text_for_message(msg_id, text)
1488
- if pending_text:
1529
+ if pending_text or pending_no_id:
1489
1530
  _flush_all_pending_text()
1490
1531
 
1491
1532
  return OpenCodeTurnOutput(text="".join(text_parts).strip(), error=error)
@@ -163,14 +163,33 @@ def _load_agent_plugins() -> dict[str, AgentDescriptor]:
163
163
  )
164
164
  continue
165
165
 
166
- if descriptor.plugin_api_version != CAR_PLUGIN_API_VERSION:
166
+ api_version_raw = getattr(descriptor, "plugin_api_version", None)
167
+ try:
168
+ api_version = int(api_version_raw)
169
+ except Exception:
170
+ api_version = None
171
+ if api_version is None:
172
+ _logger.warning(
173
+ "Ignoring agent plugin %s: invalid api_version %s",
174
+ agent_id,
175
+ api_version_raw,
176
+ )
177
+ continue
178
+ if api_version > CAR_PLUGIN_API_VERSION:
167
179
  _logger.warning(
168
- "Ignoring agent plugin %s (api_version=%s): expected %s",
180
+ "Ignoring agent plugin %s (api_version=%s) requires newer core (%s)",
169
181
  agent_id,
170
- descriptor.plugin_api_version,
182
+ api_version,
171
183
  CAR_PLUGIN_API_VERSION,
172
184
  )
173
185
  continue
186
+ if api_version < CAR_PLUGIN_API_VERSION:
187
+ _logger.info(
188
+ "Loaded agent plugin %s with older api_version=%s (current=%s)",
189
+ agent_id,
190
+ api_version,
191
+ CAR_PLUGIN_API_VERSION,
192
+ )
174
193
 
175
194
  if agent_id in _BUILTIN_AGENTS:
176
195
  _logger.warning(
@@ -11,6 +11,8 @@ from .core.config import (
11
11
  resolve_hub_config_data,
12
12
  )
13
13
  from .core.state import RunnerState, save_state
14
+ from .core.ticket_linter_cli import ensure_ticket_linter
15
+ from .core.ticket_manager_cli import ensure_ticket_manager
14
16
  from .core.utils import atomic_write
15
17
  from .manifest import load_manifest
16
18
 
@@ -19,11 +21,11 @@ GENERATED_CONFIG_HEADER = "# GENERATED by CAR - DO NOT EDIT\n"
19
21
 
20
22
 
21
23
  def sample_todo() -> str:
22
- return """# TODO\n\n- [ ] Replace this item with your first task\n- [ ] Add another task\n- [x] Example completed item\n"""
24
+ return ""
23
25
 
24
26
 
25
27
  def sample_spec() -> str:
26
- return """# Spec\n\n## Context\n- Add project background and goals here.\n\n## Requirements\n- Requirement 1\n- Requirement 2\n\n## Non-goals\n- Out of scope items\n"""
28
+ return ""
27
29
 
28
30
 
29
31
  def _seed_doc(path: Path, force: bool, content: str) -> None:
@@ -102,7 +104,7 @@ def seed_repo_files(
102
104
  workspace_dir.mkdir(parents=True, exist_ok=True)
103
105
 
104
106
  _seed_doc(workspace_dir / "active_context.md", force, sample_todo())
105
- _seed_doc(workspace_dir / "decisions.md", force, "# Decisions\n\n")
107
+ _seed_doc(workspace_dir / "decisions.md", force, "")
106
108
  _seed_doc(workspace_dir / "spec.md", force, sample_spec())
107
109
 
108
110
  # Seed an always-available briefing doc for interactive Codex sessions.
@@ -115,6 +117,8 @@ def seed_repo_files(
115
117
  },
116
118
  force=force,
117
119
  )
120
+ ensure_ticket_linter(repo_root, force=force)
121
+ ensure_ticket_manager(repo_root, force=force)
118
122
 
119
123
 
120
124
  def seed_hub_files(hub_root: Path, force: bool = False) -> None:
@@ -0,0 +1,8 @@
1
+ """Backward-compatible CLI entrypoint.
2
+
3
+ Re-export the Typer app from the CLI surface.
4
+ """
5
+
6
+ from .surfaces.cli.cli import _resolve_repo_api_path, app, main # noqa: F401
7
+
8
+ __all__ = ["app", "main", "_resolve_repo_api_path"]
@@ -0,0 +1,20 @@
1
+ """Backward-compatible Codex CLI helpers.
2
+
3
+ Delegates to core.utils to avoid duplicated logic.
4
+ """
5
+
6
+ from .core.utils import ( # noqa: F401
7
+ apply_codex_options,
8
+ extract_flag_value,
9
+ inject_flag,
10
+ supports_flag,
11
+ supports_reasoning,
12
+ )
13
+
14
+ __all__ = [
15
+ "apply_codex_options",
16
+ "extract_flag_value",
17
+ "inject_flag",
18
+ "supports_flag",
19
+ "supports_reasoning",
20
+ ]
@@ -0,0 +1,5 @@
1
+ """Core runtime primitives."""
2
+
3
+ from .archive import ArchiveResult, archive_worktree_snapshot
4
+
5
+ __all__ = ["ArchiveResult", "archive_worktree_snapshot"]
@@ -76,7 +76,8 @@ def build_about_car_markdown(
76
76
  "You are running inside **Codex Autorunner (CAR)**.\n\n"
77
77
  "CAR uses a ticket-first workflow.\n\n"
78
78
  "## Required for operation\n"
79
- "- Tickets live under `.codex-autorunner/tickets/`.\n\n"
79
+ "- Tickets live under `.codex-autorunner/tickets/`.\n"
80
+ "- Lint ticket frontmatter after edits (runs against all tickets): `python3 .codex-autorunner/bin/lint_tickets.py`.\n\n"
80
81
  "## Optional workspace docs\n"
81
82
  "- **Active context**: "
82
83
  f"`{active_context_disp}`\n"
@@ -91,6 +92,10 @@ def build_about_car_markdown(
91
92
  "- **Dispatch**: An update or message from the agent.\n"
92
93
  "- **Handoff**: Passing control from agent to user (or vice versa).\n"
93
94
  "- **Inbox**: Where the agent receives files/messages.\n\n"
95
+ "## Ticket helpers\n"
96
+ "- Use `.codex-autorunner/bin/ticket_tool.py` to list/create/insert/move tickets; it is portable and venv-free.\n"
97
+ '- Common workflows: insert gap before N (`python3 .codex-autorunner/bin/ticket_tool.py insert --before N`); move a block (`... move --start A --end B --to T`); create with auto-quoted frontmatter (`... create --title "Fix #123" --agent codex`).\n'
98
+ "- After any ticket edits, lint all tickets: `python3 .codex-autorunner/bin/lint_tickets.py`.\n\n"
94
99
  "## How CAR works (short)\n"
95
100
  "- The web UI provides ticket editing + unified file chat.\n"
96
101
  "- `car serve` starts the hub web UI. The **Terminal** tab launches the configured `codex` binary in a PTY.\n"