codex-autorunner 1.0.0__tar.gz → 1.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 (507) hide show
  1. codex_autorunner-1.2.0/PKG-INFO +150 -0
  2. codex_autorunner-1.2.0/README.md +86 -0
  3. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/pyproject.toml +7 -1
  4. codex_autorunner-1.2.0/src/codex_autorunner/__init__.py +14 -0
  5. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/agents/codex/harness.py +1 -1
  6. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/agents/opencode/client.py +113 -4
  7. codex_autorunner-1.2.0/src/codex_autorunner/agents/opencode/constants.py +3 -0
  8. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/agents/opencode/harness.py +6 -1
  9. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/agents/opencode/runtime.py +59 -18
  10. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/agents/opencode/supervisor.py +4 -0
  11. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/agents/registry.py +36 -7
  12. codex_autorunner-1.2.0/src/codex_autorunner/bootstrap.py +363 -0
  13. codex_autorunner-1.2.0/src/codex_autorunner/cli.py +8 -0
  14. codex_autorunner-1.2.0/src/codex_autorunner/codex_cli.py +20 -0
  15. codex_autorunner-1.2.0/src/codex_autorunner/core/__init__.py +21 -0
  16. codex_autorunner-1.2.0/src/codex_autorunner/core/about_car.py +268 -0
  17. codex_autorunner-1.2.0/src/codex_autorunner/core/app_server_ids.py +59 -0
  18. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/app_server_threads.py +17 -2
  19. codex_autorunner-1.0.0/src/codex_autorunner/integrations/app_server/env.py → codex_autorunner-1.2.0/src/codex_autorunner/core/app_server_utils.py +71 -16
  20. codex_autorunner-1.2.0/src/codex_autorunner/core/archive.py +349 -0
  21. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/codex_runner.py +6 -2
  22. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/config.py +433 -4
  23. codex_autorunner-1.2.0/src/codex_autorunner/core/context_awareness.py +38 -0
  24. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/drafts.py +58 -4
  25. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/exceptions.py +4 -0
  26. codex_autorunner-1.2.0/src/codex_autorunner/core/filebox.py +265 -0
  27. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/flows/controller.py +96 -2
  28. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/flows/models.py +13 -0
  29. codex_autorunner-1.2.0/src/codex_autorunner/core/flows/reasons.py +52 -0
  30. codex_autorunner-1.2.0/src/codex_autorunner/core/flows/reconciler.py +134 -0
  31. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/flows/runtime.py +57 -4
  32. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/flows/store.py +142 -7
  33. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/flows/transition.py +27 -15
  34. codex_autorunner-1.2.0/src/codex_autorunner/core/flows/ux_helpers.py +272 -0
  35. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/flows/worker_process.py +32 -6
  36. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/git_utils.py +62 -0
  37. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/hub.py +291 -20
  38. codex_autorunner-1.2.0/src/codex_autorunner/core/lifecycle_events.py +253 -0
  39. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/notifications.py +14 -2
  40. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/path_utils.py +2 -1
  41. codex_autorunner-1.2.0/src/codex_autorunner/core/pma_audit.py +224 -0
  42. codex_autorunner-1.2.0/src/codex_autorunner/core/pma_context.py +496 -0
  43. codex_autorunner-1.2.0/src/codex_autorunner/core/pma_dispatch_interceptor.py +284 -0
  44. codex_autorunner-1.2.0/src/codex_autorunner/core/pma_lifecycle.py +527 -0
  45. codex_autorunner-1.2.0/src/codex_autorunner/core/pma_queue.py +367 -0
  46. codex_autorunner-1.2.0/src/codex_autorunner/core/pma_safety.py +221 -0
  47. codex_autorunner-1.2.0/src/codex_autorunner/core/pma_state.py +115 -0
  48. {codex_autorunner-1.0.0/src/codex_autorunner/integrations/agents → codex_autorunner-1.2.0/src/codex_autorunner/core/ports}/__init__.py +6 -5
  49. {codex_autorunner-1.0.0/src/codex_autorunner/integrations/agents → codex_autorunner-1.2.0/src/codex_autorunner/core/ports}/agent_backend.py +13 -8
  50. codex_autorunner-1.2.0/src/codex_autorunner/core/ports/backend_orchestrator.py +41 -0
  51. {codex_autorunner-1.0.0/src/codex_autorunner/integrations/agents → codex_autorunner-1.2.0/src/codex_autorunner/core/ports}/run_event.py +23 -6
  52. codex_autorunner-1.2.0/src/codex_autorunner/core/prompt.py +8 -0
  53. codex_autorunner-1.2.0/src/codex_autorunner/core/prompts.py +159 -0
  54. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/redaction.py +0 -4
  55. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/review_context.py +11 -9
  56. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/runner_controller.py +35 -33
  57. codex_autorunner-1.2.0/src/codex_autorunner/core/runner_state.py +147 -0
  58. codex_autorunner-1.2.0/src/codex_autorunner/core/runtime.py +829 -0
  59. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/sqlite_utils.py +13 -4
  60. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/state.py +7 -10
  61. codex_autorunner-1.2.0/src/codex_autorunner/core/state_roots.py +62 -0
  62. codex_autorunner-1.2.0/src/codex_autorunner/core/supervisor_protocol.py +15 -0
  63. codex_autorunner-1.2.0/src/codex_autorunner/core/templates/__init__.py +39 -0
  64. codex_autorunner-1.2.0/src/codex_autorunner/core/templates/git_mirror.py +234 -0
  65. codex_autorunner-1.2.0/src/codex_autorunner/core/templates/provenance.py +56 -0
  66. codex_autorunner-1.2.0/src/codex_autorunner/core/templates/scan_cache.py +120 -0
  67. codex_autorunner-1.2.0/src/codex_autorunner/core/text_delta_coalescer.py +97 -0
  68. codex_autorunner-1.2.0/src/codex_autorunner/core/ticket_linter_cli.py +218 -0
  69. codex_autorunner-1.2.0/src/codex_autorunner/core/ticket_manager_cli.py +494 -0
  70. codex_autorunner-1.2.0/src/codex_autorunner/core/time_utils.py +11 -0
  71. codex_autorunner-1.2.0/src/codex_autorunner/core/types.py +18 -0
  72. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/update.py +4 -5
  73. codex_autorunner-1.2.0/src/codex_autorunner/core/update_paths.py +28 -0
  74. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/usage.py +164 -12
  75. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/utils.py +125 -15
  76. codex_autorunner-1.2.0/src/codex_autorunner/flows/review/__init__.py +17 -0
  77. codex_autorunner-1.0.0/src/codex_autorunner/core/review.py → codex_autorunner-1.2.0/src/codex_autorunner/flows/review/service.py +37 -34
  78. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/flows/ticket_flow/definition.py +52 -3
  79. codex_autorunner-1.2.0/src/codex_autorunner/integrations/agents/__init__.py +19 -0
  80. codex_autorunner-1.2.0/src/codex_autorunner/integrations/agents/backend_orchestrator.py +302 -0
  81. codex_autorunner-1.2.0/src/codex_autorunner/integrations/agents/codex_adapter.py +90 -0
  82. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/agents/codex_backend.py +177 -25
  83. codex_autorunner-1.2.0/src/codex_autorunner/integrations/agents/opencode_adapter.py +108 -0
  84. codex_autorunner-1.2.0/src/codex_autorunner/integrations/agents/opencode_backend.py +598 -0
  85. codex_autorunner-1.2.0/src/codex_autorunner/integrations/agents/runner.py +86 -0
  86. codex_autorunner-1.2.0/src/codex_autorunner/integrations/agents/wiring.py +279 -0
  87. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/app_server/client.py +7 -60
  88. codex_autorunner-1.2.0/src/codex_autorunner/integrations/app_server/env.py +5 -0
  89. codex_autorunner-1.0.0/src/codex_autorunner/core/app_server_events.py → codex_autorunner-1.2.0/src/codex_autorunner/integrations/app_server/event_buffer.py +15 -8
  90. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/adapter.py +65 -0
  91. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/config.py +46 -0
  92. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/constants.py +1 -1
  93. codex_autorunner-1.2.0/src/codex_autorunner/integrations/telegram/doctor.py +269 -0
  94. codex_autorunner-1.2.0/src/codex_autorunner/integrations/telegram/handlers/__init__.py +0 -0
  95. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/handlers/callbacks.py +7 -0
  96. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/handlers/commands/execution.py +236 -74
  97. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/handlers/commands/files.py +314 -75
  98. codex_autorunner-1.2.0/src/codex_autorunner/integrations/telegram/handlers/commands/flows.py +1652 -0
  99. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/handlers/commands/workspace.py +498 -37
  100. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/handlers/commands_runtime.py +206 -48
  101. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/handlers/commands_spec.py +20 -3
  102. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/handlers/messages.py +27 -1
  103. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/handlers/selections.py +61 -1
  104. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/helpers.py +22 -1
  105. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/runtime.py +9 -4
  106. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/service.py +45 -10
  107. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/state.py +38 -0
  108. codex_autorunner-1.2.0/src/codex_autorunner/integrations/telegram/ticket_flow_bridge.py +617 -0
  109. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/transport.py +13 -4
  110. codex_autorunner-1.2.0/src/codex_autorunner/integrations/templates/__init__.py +27 -0
  111. codex_autorunner-1.2.0/src/codex_autorunner/integrations/templates/scan_agent.py +312 -0
  112. codex_autorunner-1.2.0/src/codex_autorunner/routes/__init__.py +37 -0
  113. codex_autorunner-1.2.0/src/codex_autorunner/routes/agents.py +3 -0
  114. codex_autorunner-1.2.0/src/codex_autorunner/routes/analytics.py +3 -0
  115. codex_autorunner-1.2.0/src/codex_autorunner/routes/app_server.py +3 -0
  116. codex_autorunner-1.2.0/src/codex_autorunner/routes/base.py +3 -0
  117. codex_autorunner-1.2.0/src/codex_autorunner/routes/file_chat.py +7 -0
  118. codex_autorunner-1.2.0/src/codex_autorunner/routes/flows.py +7 -0
  119. codex_autorunner-1.2.0/src/codex_autorunner/routes/messages.py +7 -0
  120. codex_autorunner-1.2.0/src/codex_autorunner/routes/repos.py +3 -0
  121. codex_autorunner-1.2.0/src/codex_autorunner/routes/review.py +3 -0
  122. codex_autorunner-1.2.0/src/codex_autorunner/routes/sessions.py +3 -0
  123. codex_autorunner-1.2.0/src/codex_autorunner/routes/settings.py +3 -0
  124. codex_autorunner-1.2.0/src/codex_autorunner/routes/shared.py +3 -0
  125. codex_autorunner-1.2.0/src/codex_autorunner/routes/system.py +7 -0
  126. codex_autorunner-1.2.0/src/codex_autorunner/routes/usage.py +3 -0
  127. codex_autorunner-1.2.0/src/codex_autorunner/routes/voice.py +3 -0
  128. codex_autorunner-1.2.0/src/codex_autorunner/routes/workspace.py +3 -0
  129. codex_autorunner-1.2.0/src/codex_autorunner/server.py +17 -0
  130. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/agentControls.js +61 -16
  131. codex_autorunner-1.2.0/src/codex_autorunner/static/app.js +217 -0
  132. codex_autorunner-1.2.0/src/codex_autorunner/static/archive.js +826 -0
  133. codex_autorunner-1.2.0/src/codex_autorunner/static/archiveApi.js +37 -0
  134. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/autoRefresh.js +7 -7
  135. codex_autorunner-1.2.0/src/codex_autorunner/static/chatUploads.js +137 -0
  136. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/dashboard.js +224 -171
  137. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/docChatCore.js +185 -13
  138. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/fileChat.js +68 -40
  139. codex_autorunner-1.2.0/src/codex_autorunner/static/fileboxUi.js +159 -0
  140. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/hub.js +114 -131
  141. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/index.html +375 -49
  142. codex_autorunner-1.2.0/src/codex_autorunner/static/messages.js +951 -0
  143. codex_autorunner-1.2.0/src/codex_autorunner/static/notifications.js +255 -0
  144. codex_autorunner-1.2.0/src/codex_autorunner/static/pma.js +1167 -0
  145. codex_autorunner-1.2.0/src/codex_autorunner/static/preserve.js +17 -0
  146. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/settings.js +128 -6
  147. codex_autorunner-1.2.0/src/codex_autorunner/static/smartRefresh.js +52 -0
  148. codex_autorunner-1.2.0/src/codex_autorunner/static/streamUtils.js +57 -0
  149. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/styles.css +9798 -6143
  150. codex_autorunner-1.2.0/src/codex_autorunner/static/tabs.js +205 -0
  151. codex_autorunner-1.2.0/src/codex_autorunner/static/templateReposSettings.js +225 -0
  152. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/terminal.js +18 -0
  153. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/ticketChatActions.js +165 -3
  154. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/ticketChatStream.js +17 -119
  155. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/ticketEditor.js +137 -15
  156. codex_autorunner-1.2.0/src/codex_autorunner/static/ticketTemplates.js +798 -0
  157. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/tickets.js +821 -98
  158. codex_autorunner-1.2.0/src/codex_autorunner/static/turnEvents.js +27 -0
  159. codex_autorunner-1.2.0/src/codex_autorunner/static/turnResume.js +33 -0
  160. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/utils.js +39 -0
  161. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/workspace.js +389 -82
  162. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/workspaceFileBrowser.js +15 -13
  163. codex_autorunner-1.2.0/src/codex_autorunner/surfaces/__init__.py +5 -0
  164. codex_autorunner-1.2.0/src/codex_autorunner/surfaces/cli/__init__.py +6 -0
  165. codex_autorunner-1.2.0/src/codex_autorunner/surfaces/cli/cli.py +2534 -0
  166. codex_autorunner-1.2.0/src/codex_autorunner/surfaces/cli/codex_cli.py +20 -0
  167. codex_autorunner-1.2.0/src/codex_autorunner/surfaces/cli/pma_cli.py +817 -0
  168. codex_autorunner-1.2.0/src/codex_autorunner/surfaces/telegram/__init__.py +3 -0
  169. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.2.0/src/codex_autorunner/surfaces}/web/app.py +344 -71
  170. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.2.0/src/codex_autorunner/surfaces}/web/hub_jobs.py +2 -2
  171. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.2.0/src/codex_autorunner/surfaces}/web/middleware.py +3 -3
  172. codex_autorunner-1.2.0/src/codex_autorunner/surfaces/web/review.py +6 -0
  173. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.2.0/src/codex_autorunner/surfaces/web}/routes/__init__.py +6 -0
  174. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.2.0/src/codex_autorunner/surfaces/web}/routes/agents.py +4 -4
  175. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.2.0/src/codex_autorunner/surfaces/web}/routes/analytics.py +71 -26
  176. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.2.0/src/codex_autorunner/surfaces/web}/routes/app_server.py +4 -4
  177. codex_autorunner-1.2.0/src/codex_autorunner/surfaces/web/routes/archive.py +357 -0
  178. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.2.0/src/codex_autorunner/surfaces/web}/routes/base.py +26 -8
  179. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.2.0/src/codex_autorunner/surfaces/web}/routes/file_chat.py +324 -43
  180. codex_autorunner-1.2.0/src/codex_autorunner/surfaces/web/routes/filebox.py +227 -0
  181. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.2.0/src/codex_autorunner/surfaces/web}/routes/flows.py +497 -123
  182. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.2.0/src/codex_autorunner/surfaces/web}/routes/messages.py +76 -45
  183. codex_autorunner-1.2.0/src/codex_autorunner/surfaces/web/routes/pma.py +1652 -0
  184. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.2.0/src/codex_autorunner/surfaces/web}/routes/repos.py +3 -3
  185. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.2.0/src/codex_autorunner/surfaces/web}/routes/review.py +2 -2
  186. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.2.0/src/codex_autorunner/surfaces/web}/routes/sessions.py +2 -2
  187. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.2.0/src/codex_autorunner/surfaces/web}/routes/settings.py +2 -2
  188. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.2.0/src/codex_autorunner/surfaces/web}/routes/shared.py +8 -7
  189. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.2.0/src/codex_autorunner/surfaces/web}/routes/system.py +8 -8
  190. codex_autorunner-1.2.0/src/codex_autorunner/surfaces/web/routes/templates.py +634 -0
  191. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.2.0/src/codex_autorunner/surfaces/web}/routes/usage.py +4 -2
  192. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.2.0/src/codex_autorunner/surfaces/web}/routes/voice.py +1 -1
  193. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.2.0/src/codex_autorunner/surfaces/web}/routes/workspace.py +11 -11
  194. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.2.0/src/codex_autorunner/surfaces}/web/runner_manager.py +3 -3
  195. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.2.0/src/codex_autorunner/surfaces}/web/schemas.py +110 -18
  196. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.2.0/src/codex_autorunner/surfaces}/web/static_assets.py +48 -2
  197. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.2.0/src/codex_autorunner/surfaces}/web/static_refresh.py +1 -1
  198. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.2.0/src/codex_autorunner/surfaces}/web/terminal_sessions.py +1 -1
  199. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/tickets/__init__.py +8 -1
  200. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/tickets/agent_pool.py +53 -4
  201. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/tickets/files.py +37 -16
  202. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/tickets/lint.py +50 -0
  203. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/tickets/models.py +6 -1
  204. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/tickets/outbox.py +50 -2
  205. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/tickets/runner.py +396 -57
  206. codex_autorunner-1.2.0/src/codex_autorunner/web/__init__.py +5 -0
  207. codex_autorunner-1.2.0/src/codex_autorunner/web/app.py +3 -0
  208. codex_autorunner-1.2.0/src/codex_autorunner/web/hub_jobs.py +3 -0
  209. codex_autorunner-1.2.0/src/codex_autorunner/web/middleware.py +3 -0
  210. codex_autorunner-1.2.0/src/codex_autorunner/web/pty_session.py +3 -0
  211. codex_autorunner-1.2.0/src/codex_autorunner/web/runner_manager.py +3 -0
  212. codex_autorunner-1.2.0/src/codex_autorunner/web/schemas.py +3 -0
  213. codex_autorunner-1.2.0/src/codex_autorunner/web/static_assets.py +7 -0
  214. codex_autorunner-1.2.0/src/codex_autorunner/web/static_refresh.py +3 -0
  215. codex_autorunner-1.2.0/src/codex_autorunner/web/terminal_sessions.py +3 -0
  216. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/workspace/paths.py +49 -33
  217. codex_autorunner-1.2.0/src/codex_autorunner.egg-info/PKG-INFO +150 -0
  218. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner.egg-info/SOURCES.txt +133 -13
  219. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_about_car_terminal_context.py +4 -3
  220. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_agent_run_events.py +3 -3
  221. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_agents_registry.py +116 -0
  222. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_api_contract.py +5 -0
  223. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_app_server_events.py +1 -1
  224. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_app_server_thread_registry.py +10 -1
  225. codex_autorunner-1.2.0/tests/test_archive_worktree.py +121 -0
  226. codex_autorunner-1.2.0/tests/test_cli_hub_snapshot.py +206 -0
  227. codex_autorunner-1.2.0/tests/test_cli_hub_worktree.py +172 -0
  228. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_cli_status.py +0 -3
  229. codex_autorunner-1.2.0/tests/test_cli_templates_apply.py +250 -0
  230. codex_autorunner-1.2.0/tests/test_cli_templates_fetch.py +154 -0
  231. codex_autorunner-1.2.0/tests/test_cli_templates_repos.py +319 -0
  232. codex_autorunner-1.2.0/tests/test_cli_ticket_flow_guard.py +38 -0
  233. codex_autorunner-1.2.0/tests/test_codex_backend_security.py +167 -0
  234. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_codex_runner.py +3 -3
  235. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_core_web_boundary.py +3 -3
  236. codex_autorunner-1.2.0/tests/test_doctor_checks.py +118 -0
  237. codex_autorunner-1.2.0/tests/test_durable_writes.py +143 -0
  238. codex_autorunner-1.2.0/tests/test_file_chat_prompt.py +26 -0
  239. codex_autorunner-1.2.0/tests/test_filebox.py +85 -0
  240. codex_autorunner-1.2.0/tests/test_hub_app_context.py +24 -0
  241. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_hub_create.py +19 -3
  242. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_hub_supervisor.py +88 -25
  243. codex_autorunner-1.2.0/tests/test_lifecycle_events.py +130 -0
  244. codex_autorunner-1.2.0/tests/test_opencode_agent_pool.py +555 -0
  245. codex_autorunner-1.2.0/tests/test_opencode_backend_streaming.py +128 -0
  246. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_opencode_runtime.py +33 -0
  247. codex_autorunner-1.2.0/tests/test_pma_audit_safety.py +163 -0
  248. codex_autorunner-1.2.0/tests/test_pma_bootstrap.py +56 -0
  249. codex_autorunner-1.2.0/tests/test_pma_cli.py +298 -0
  250. codex_autorunner-1.2.0/tests/test_pma_context.py +348 -0
  251. codex_autorunner-1.2.0/tests/test_pma_lifecycle.py +137 -0
  252. codex_autorunner-1.2.0/tests/test_pma_routes.py +693 -0
  253. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_redaction.py +1 -9
  254. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_review_context.py +5 -11
  255. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_review_service.py +3 -3
  256. codex_autorunner-1.2.0/tests/test_runner_controller.py +80 -0
  257. codex_autorunner-1.2.0/tests/test_runner_state.py +103 -0
  258. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_telegram_adapter.py +10 -0
  259. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_telegram_bot_config.py +49 -0
  260. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_telegram_cache_cleanup.py +10 -0
  261. codex_autorunner-1.2.0/tests/test_telegram_car_context.py +18 -0
  262. codex_autorunner-1.2.0/tests/test_telegram_files_pma.py +99 -0
  263. codex_autorunner-1.2.0/tests/test_telegram_flow_aliases.py +75 -0
  264. codex_autorunner-1.2.0/tests/test_telegram_flow_bootstrap.py +172 -0
  265. codex_autorunner-1.2.0/tests/test_telegram_flow_callback_actions.py +167 -0
  266. codex_autorunner-1.2.0/tests/test_telegram_flow_commands.py +22 -0
  267. codex_autorunner-1.2.0/tests/test_telegram_flow_lifecycle.py +206 -0
  268. codex_autorunner-1.2.0/tests/test_telegram_flow_status.py +339 -0
  269. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_telegram_handlers_callbacks.py +49 -0
  270. codex_autorunner-1.2.0/tests/test_telegram_pma_routing.py +702 -0
  271. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_telegram_state.py +22 -1
  272. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_telegram_status_rate_limits.py +16 -0
  273. codex_autorunner-1.2.0/tests/test_telegram_ticket_flow_bridge.py +190 -0
  274. codex_autorunner-1.2.0/tests/test_ticket_linter_cli.py +118 -0
  275. codex_autorunner-1.2.0/tests/test_ticket_manager_cli.py +113 -0
  276. codex_autorunner-1.2.0/tests/test_time_utils.py +17 -0
  277. codex_autorunner-1.2.0/tests/test_update_paths.py +28 -0
  278. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_usage.py +94 -0
  279. codex_autorunner-1.2.0/tests/test_workspace_paths.py +89 -0
  280. codex_autorunner-1.0.0/PKG-INFO +0 -246
  281. codex_autorunner-1.0.0/README.md +0 -182
  282. codex_autorunner-1.0.0/src/codex_autorunner/__init__.py +0 -3
  283. codex_autorunner-1.0.0/src/codex_autorunner/bootstrap.py +0 -141
  284. codex_autorunner-1.0.0/src/codex_autorunner/cli.py +0 -1177
  285. codex_autorunner-1.0.0/src/codex_autorunner/codex_cli.py +0 -84
  286. codex_autorunner-1.0.0/src/codex_autorunner/core/__init__.py +0 -1
  287. codex_autorunner-1.0.0/src/codex_autorunner/core/about_car.py +0 -150
  288. codex_autorunner-1.0.0/src/codex_autorunner/core/adapter_utils.py +0 -21
  289. codex_autorunner-1.0.0/src/codex_autorunner/core/docs.py +0 -122
  290. codex_autorunner-1.0.0/src/codex_autorunner/core/engine.py +0 -2653
  291. codex_autorunner-1.0.0/src/codex_autorunner/core/prompt.py +0 -88
  292. codex_autorunner-1.0.0/src/codex_autorunner/core/prompts.py +0 -275
  293. codex_autorunner-1.0.0/src/codex_autorunner/core/static_assets.py +0 -55
  294. codex_autorunner-1.0.0/src/codex_autorunner/core/text_delta_coalescer.py +0 -43
  295. codex_autorunner-1.0.0/src/codex_autorunner/integrations/agents/opencode_backend.py +0 -325
  296. codex_autorunner-1.0.0/src/codex_autorunner/integrations/telegram/doctor.py +0 -47
  297. codex_autorunner-1.0.0/src/codex_autorunner/integrations/telegram/handlers/commands/flows.py +0 -227
  298. codex_autorunner-1.0.0/src/codex_autorunner/integrations/telegram/ticket_flow_bridge.py +0 -322
  299. codex_autorunner-1.0.0/src/codex_autorunner/server.py +0 -17
  300. codex_autorunner-1.0.0/src/codex_autorunner/static/app.js +0 -105
  301. codex_autorunner-1.0.0/src/codex_autorunner/static/messages.js +0 -470
  302. codex_autorunner-1.0.0/src/codex_autorunner/static/tabs.js +0 -64
  303. codex_autorunner-1.0.0/src/codex_autorunner.egg-info/PKG-INFO +0 -246
  304. codex_autorunner-1.0.0/tests/test_engine_app_server.py +0 -161
  305. codex_autorunner-1.0.0/tests/test_engine_end_review.py +0 -102
  306. codex_autorunner-1.0.0/tests/test_engine_logs.py +0 -34
  307. codex_autorunner-1.0.0/tests/test_prompt.py +0 -51
  308. codex_autorunner-1.0.0/tests/test_runner_controller.py +0 -295
  309. codex_autorunner-1.0.0/tests/test_sse_streams.py +0 -26
  310. codex_autorunner-1.0.0/tests/test_workspace_paths.py +0 -42
  311. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/LICENSE +0 -0
  312. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/setup.cfg +0 -0
  313. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/__main__.py +0 -0
  314. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/agents/__init__.py +0 -0
  315. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/agents/base.py +0 -0
  316. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/agents/codex/__init__.py +0 -0
  317. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/agents/opencode/__init__.py +0 -0
  318. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/agents/opencode/agent_config.py +0 -0
  319. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/agents/opencode/events.py +0 -0
  320. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/agents/opencode/logging.py +0 -0
  321. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/agents/opencode/run_prompt.py +0 -0
  322. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/agents/types.py +0 -0
  323. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/api.py +0 -0
  324. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/codex_runner.py +0 -0
  325. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/app_server_logging.py +0 -0
  326. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/app_server_prompts.py +0 -0
  327. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/circuit_breaker.py +0 -0
  328. /codex_autorunner-1.0.0/src/codex_autorunner/integrations/telegram/handlers/__init__.py → /codex_autorunner-1.2.0/src/codex_autorunner/core/docs.py +0 -0
  329. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/flows/__init__.py +0 -0
  330. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/flows/definition.py +0 -0
  331. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/injected_context.py +0 -0
  332. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/locks.py +0 -0
  333. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/logging_utils.py +0 -0
  334. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/optional_dependencies.py +0 -0
  335. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/patch_utils.py +0 -0
  336. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/request_context.py +0 -0
  337. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/retry.py +0 -0
  338. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/run_index.py +0 -0
  339. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/runner_process.py +0 -0
  340. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/supervisor_utils.py +0 -0
  341. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/core/update_runner.py +0 -0
  342. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/discovery.py +0 -0
  343. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/flows/ticket_flow/__init__.py +0 -0
  344. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/housekeeping.py +0 -0
  345. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/__init__.py +0 -0
  346. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/app_server/__init__.py +0 -0
  347. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/app_server/supervisor.py +0 -0
  348. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/github/__init__.py +0 -0
  349. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/github/service.py +0 -0
  350. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/__init__.py +0 -0
  351. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/api_schemas.py +0 -0
  352. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/commands_registry.py +0 -0
  353. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/dispatch.py +0 -0
  354. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/handlers/approvals.py +0 -0
  355. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/handlers/commands/__init__.py +0 -0
  356. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/handlers/commands/approvals.py +0 -0
  357. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/handlers/commands/formatting.py +0 -0
  358. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/handlers/commands/github.py +0 -0
  359. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/handlers/commands/shared.py +0 -0
  360. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/handlers/commands/voice.py +0 -0
  361. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/handlers/questions.py +0 -0
  362. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/handlers/utils.py +0 -0
  363. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/notifications.py +0 -0
  364. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/outbox.py +0 -0
  365. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/overflow.py +0 -0
  366. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/progress_stream.py +0 -0
  367. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/rendering.py +0 -0
  368. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/retry.py +0 -0
  369. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/trigger_mode.py +0 -0
  370. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/types.py +0 -0
  371. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/integrations/telegram/voice.py +0 -0
  372. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/manifest.py +0 -0
  373. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/plugin_api.py +0 -0
  374. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/agentEvents.js +0 -0
  375. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/bootstrap.js +0 -0
  376. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/bus.js +0 -0
  377. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/cache.js +0 -0
  378. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/constants.js +0 -0
  379. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/diffRenderer.js +0 -0
  380. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/docChatStorage.js +0 -0
  381. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/docChatVoice.js +0 -0
  382. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/docEditor.js +0 -0
  383. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/env.js +0 -0
  384. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/eventSummarizer.js +0 -0
  385. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/health.js +0 -0
  386. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/liveUpdates.js +0 -0
  387. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/loader.js +0 -0
  388. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/mobileCompact.js +0 -0
  389. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/terminalManager.js +0 -0
  390. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/ticketChatEvents.js +0 -0
  391. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/ticketChatStorage.js +0 -0
  392. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/ticketVoice.js +0 -0
  393. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/vendor/LICENSE.xterm +0 -0
  394. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-400-cyrillic-ext.woff2 +0 -0
  395. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-400-cyrillic.woff2 +0 -0
  396. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-400-greek.woff2 +0 -0
  397. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-400-latin-ext.woff2 +0 -0
  398. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-400-latin.woff2 +0 -0
  399. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-400-vietnamese.woff2 +0 -0
  400. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-500-cyrillic-ext.woff2 +0 -0
  401. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-500-cyrillic.woff2 +0 -0
  402. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-500-greek.woff2 +0 -0
  403. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-500-latin-ext.woff2 +0 -0
  404. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-500-latin.woff2 +0 -0
  405. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-500-vietnamese.woff2 +0 -0
  406. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-600-cyrillic-ext.woff2 +0 -0
  407. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-600-cyrillic.woff2 +0 -0
  408. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-600-greek.woff2 +0 -0
  409. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-600-latin-ext.woff2 +0 -0
  410. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-600-latin.woff2 +0 -0
  411. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-600-vietnamese.woff2 +0 -0
  412. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/OFL.txt +0 -0
  413. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/vendor/xterm-addon-fit.js +0 -0
  414. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/vendor/xterm.css +0 -0
  415. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/vendor/xterm.js +0 -0
  416. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/voice.js +0 -0
  417. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/static/workspaceApi.js +0 -0
  418. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.2.0/src/codex_autorunner/surfaces}/web/__init__.py +0 -0
  419. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.2.0/src/codex_autorunner/surfaces}/web/pty_session.py +0 -0
  420. {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.2.0/src/codex_autorunner/surfaces/web}/routes/terminal_images.py +0 -0
  421. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/tickets/frontmatter.py +0 -0
  422. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/tickets/replies.py +0 -0
  423. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/tickets/spec_ingest.py +0 -0
  424. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/voice/__init__.py +0 -0
  425. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/voice/capture.py +0 -0
  426. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/voice/config.py +0 -0
  427. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/voice/provider.py +0 -0
  428. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/voice/providers/__init__.py +0 -0
  429. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/voice/providers/openai_whisper.py +0 -0
  430. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/voice/resolver.py +0 -0
  431. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/voice/service.py +0 -0
  432. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner/workspace/__init__.py +0 -0
  433. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner.egg-info/dependency_links.txt +0 -0
  434. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner.egg-info/entry_points.txt +0 -0
  435. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner.egg-info/requires.txt +0 -0
  436. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/src/codex_autorunner.egg-info/top_level.txt +0 -0
  437. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_agents_plugins.py +0 -0
  438. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_app_server_client.py +0 -0
  439. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_app_server_event_formatter.py +0 -0
  440. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_app_server_prompts.py +0 -0
  441. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_app_server_supervisor.py +0 -0
  442. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_auth_middleware.py +0 -0
  443. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_base_path.py +0 -0
  444. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_base_path_static.py +0 -0
  445. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_cli_init.py +0 -0
  446. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_cli_sessions.py +0 -0
  447. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_codex_app_server_integration.py +0 -0
  448. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_codex_cli_flags.py +0 -0
  449. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_config_resolution.py +0 -0
  450. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_file_chat_drafts.py +0 -0
  451. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_housekeeping.py +0 -0
  452. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_hub_foundation.py +0 -0
  453. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_hub_terminal_sessions.py +0 -0
  454. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_hub_ui_escape.py +0 -0
  455. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_lock_utils.py +0 -0
  456. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_logging_utils.py +0 -0
  457. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_notifications.py +0 -0
  458. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_opencode_agent_config.py +0 -0
  459. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_opencode_client.py +0 -0
  460. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_opencode_event_formatter.py +0 -0
  461. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_opencode_integration.py +0 -0
  462. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_opencode_review_arguments.py +0 -0
  463. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_optional_dependencies.py +0 -0
  464. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_origin_middleware.py +0 -0
  465. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_patch_utils.py +0 -0
  466. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_request_logging.py +0 -0
  467. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_state_lock.py +0 -0
  468. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_state_sessions.py +0 -0
  469. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_static.py +0 -0
  470. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_static_asset_cache.py +0 -0
  471. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_system_update_check.py +0 -0
  472. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_system_update_worker.py +0 -0
  473. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_telegram_bot_integration.py +0 -0
  474. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_telegram_bot_lock.py +0 -0
  475. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_telegram_codex_feature_flags.py +0 -0
  476. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_telegram_command_registry.py +0 -0
  477. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_telegram_fast_ack.py +0 -0
  478. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_telegram_handlers_messages.py +0 -0
  479. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_telegram_interrupt_status.py +0 -0
  480. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_telegram_media_batch_failure.py +0 -0
  481. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_telegram_opencode_context_cache.py +0 -0
  482. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_telegram_opencode_usage.py +0 -0
  483. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_telegram_outbox.py +0 -0
  484. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_telegram_overflow.py +0 -0
  485. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_telegram_paths_compatible.py +0 -0
  486. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_telegram_progress_stream.py +0 -0
  487. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_telegram_review_opencode.py +0 -0
  488. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_telegram_task_tracking.py +0 -0
  489. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_telegram_thread_paths.py +0 -0
  490. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_telegram_topic_queue.py +0 -0
  491. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_telegram_transport.py +0 -0
  492. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_telegram_trigger_mode.py +0 -0
  493. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_telegram_turn_queue.py +0 -0
  494. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_telegram_update_dedupe.py +0 -0
  495. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_telegram_whisper_disclaimer.py +0 -0
  496. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_terminal_idle_timeout.py +0 -0
  497. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_terminal_input_dedupe.py +0 -0
  498. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_ticket_flow_approval_config.py +0 -0
  499. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_voice_capture.py +0 -0
  500. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_voice_config.py +0 -0
  501. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_voice_service.py +0 -0
  502. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_voice_transcribe_endpoint.py +0 -0
  503. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_voice_ui.py +0 -0
  504. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_voice_whisper_mime_types.py +0 -0
  505. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_voice_whisper_provider.py +0 -0
  506. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_workspace_functional.py +0 -0
  507. {codex_autorunner-1.0.0 → codex_autorunner-1.2.0}/tests/test_workspace_helpers.py +0 -0
@@ -0,0 +1,150 @@
1
+ Metadata-Version: 2.4
2
+ Name: codex-autorunner
3
+ Version: 1.2.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 3 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
+ ### Project Manager Agent
99
+ The project manager agent (PMA) is a way to use an AI agent to run CAR. For example instead of making/editing tickets in the UI, you can ask the PMA to do it for you. Instead of starting a ticket flow, the PMA can babysit it for you. The PMA can be accessed in the web and in Telegram, and also uses the CAR CLI directly.
100
+
101
+ ## Quickstart
102
+
103
+ 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.
104
+
105
+ ### From source (repo checkout)
106
+
107
+ If you're working from a fresh clone of this repo, you can run the repo-local CLI shim:
108
+
109
+ ```bash
110
+ ./car --help
111
+ ```
112
+
113
+ The shim will try `PYTHONPATH=src` first and, if dependencies are missing, will bootstrap a local `.venv` and install CAR.
114
+
115
+ ## Supported models
116
+ CAR currently supports:
117
+ - Codex
118
+ - Opencode
119
+
120
+ 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.
121
+
122
+ ## Examples
123
+ Build out complex features and products by providing a series of tickets assigned to various agents.
124
+ ![CAR Tickets in Progress Screenshot](docs/screenshots/tickets-in-progress.png)
125
+
126
+ Tickets are just markdown files that both you and the agent can edit.
127
+ ![CAR Ticket Markdown Screenshot](docs/screenshots/ticket-markdown.png)
128
+
129
+ You don't have to babysit the agents, they inbox you or ping you on Telegram.
130
+ ![CAR Inbox Screenshot](docs/screenshots/inbox.png)
131
+
132
+ 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.
133
+ ![CAR Workspace Screenshot](docs/screenshots/workspace.png)
134
+
135
+ All core workspace documents are also just markdown files, so you and the agent can easily edit them.
136
+ ![CAR Workspace New MD Screenshot](docs/screenshots/workspace-new-md.png)
137
+
138
+ If you need to do something more custom or granular, you can use your favorite agent TUIs in the built-in terminal.
139
+ ![CAR Terminal Codex Screenshot](docs/screenshots/terminal-codex.png)
140
+ ![CAR Terminal Opencode Screenshot](docs/screenshots/terminal-opencode.png)
141
+
142
+ On the go? The web UI is mobile responsive, or if you prefer you can type or voice chat with your agents on Telegram.
143
+ ![CAR Telegram Media Voice Screenshot](docs/screenshots/telegram-media-voice.PNG)
144
+ ![CAR Telegram Media Image Screenshot](docs/screenshots/telegram-media-image.PNG)
145
+
146
+ Don't want to use the product directly? Delegate work to the PMA.
147
+ ![CAR Telegram PMA Screenshot](docs/screenshots/telegram-pma.png)
148
+
149
+ ## Star history
150
+ [![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,86 @@
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 3 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
+ ### Project Manager Agent
35
+ The project manager agent (PMA) is a way to use an AI agent to run CAR. For example instead of making/editing tickets in the UI, you can ask the PMA to do it for you. Instead of starting a ticket flow, the PMA can babysit it for you. The PMA can be accessed in the web and in Telegram, and also uses the CAR CLI directly.
36
+
37
+ ## Quickstart
38
+
39
+ 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.
40
+
41
+ ### From source (repo checkout)
42
+
43
+ If you're working from a fresh clone of this repo, you can run the repo-local CLI shim:
44
+
45
+ ```bash
46
+ ./car --help
47
+ ```
48
+
49
+ The shim will try `PYTHONPATH=src` first and, if dependencies are missing, will bootstrap a local `.venv` and install CAR.
50
+
51
+ ## Supported models
52
+ CAR currently supports:
53
+ - Codex
54
+ - Opencode
55
+
56
+ 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.
57
+
58
+ ## Examples
59
+ Build out complex features and products by providing a series of tickets assigned to various agents.
60
+ ![CAR Tickets in Progress Screenshot](docs/screenshots/tickets-in-progress.png)
61
+
62
+ Tickets are just markdown files that both you and the agent can edit.
63
+ ![CAR Ticket Markdown Screenshot](docs/screenshots/ticket-markdown.png)
64
+
65
+ You don't have to babysit the agents, they inbox you or ping you on Telegram.
66
+ ![CAR Inbox Screenshot](docs/screenshots/inbox.png)
67
+
68
+ 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.
69
+ ![CAR Workspace Screenshot](docs/screenshots/workspace.png)
70
+
71
+ All core workspace documents are also just markdown files, so you and the agent can easily edit them.
72
+ ![CAR Workspace New MD Screenshot](docs/screenshots/workspace-new-md.png)
73
+
74
+ If you need to do something more custom or granular, you can use your favorite agent TUIs in the built-in terminal.
75
+ ![CAR Terminal Codex Screenshot](docs/screenshots/terminal-codex.png)
76
+ ![CAR Terminal Opencode Screenshot](docs/screenshots/terminal-opencode.png)
77
+
78
+ On the go? The web UI is mobile responsive, or if you prefer you can type or voice chat with your agents on Telegram.
79
+ ![CAR Telegram Media Voice Screenshot](docs/screenshots/telegram-media-voice.PNG)
80
+ ![CAR Telegram Media Image Screenshot](docs/screenshots/telegram-media-image.PNG)
81
+
82
+ Don't want to use the product directly? Delegate work to the PMA.
83
+ ![CAR Telegram PMA Screenshot](docs/screenshots/telegram-pma.png)
84
+
85
+ ## Star history
86
+ [![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.2.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,12 @@ 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"]
111
+ "src/codex_autorunner/surfaces/cli/pma_cli.py" = ["B008"]
108
112
  "src/codex_autorunner/routes/terminal_images.py" = ["B008"]
113
+ "src/codex_autorunner/surfaces/web/routes/terminal_images.py" = ["B008"]
109
114
  "src/codex_autorunner/routes/voice.py" = ["B008"]
115
+ "src/codex_autorunner/surfaces/web/routes/voice.py" = ["B008"]
110
116
 
111
117
  [tool.mypy]
112
118
  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
@@ -21,6 +21,7 @@ class OpenCodeApiProfile:
21
21
 
22
22
  supports_prompt_async: bool = True
23
23
  supports_global_endpoints: bool = True
24
+ max_text_chars: Optional[int] = None
24
25
  spec_fetched: bool = False
25
26
 
26
27
 
@@ -83,6 +84,7 @@ class OpenCodeClient:
83
84
  *,
84
85
  auth: Optional[tuple[str, str]] = None,
85
86
  timeout: Optional[float] = None,
87
+ max_text_chars: Optional[int] = None,
86
88
  logger: Optional[logging.Logger] = None,
87
89
  ) -> None:
88
90
  self._client = httpx.AsyncClient(
@@ -93,6 +95,10 @@ class OpenCodeClient:
93
95
  self._logger = logger or logging.getLogger(__name__)
94
96
  self._api_profile: Optional[OpenCodeApiProfile] = None
95
97
  self._api_profile_lock = asyncio.Lock()
98
+ self._max_text_chars_override = (
99
+ int(max_text_chars) if isinstance(max_text_chars, int) else None
100
+ )
101
+ self._max_text_chars_cache: Optional[int] = None
96
102
 
97
103
  async def close(self) -> None:
98
104
  await self._client.aclose()
@@ -121,6 +127,7 @@ class OpenCodeClient:
121
127
  profile.supports_global_endpoints = self.has_endpoint(
122
128
  spec, "get", "/global/health"
123
129
  ) or self.has_endpoint(spec, "get", "/global/event")
130
+ profile.max_text_chars = self._extract_max_text_chars(spec)
124
131
 
125
132
  log_event(
126
133
  self._logger,
@@ -147,6 +154,103 @@ class OpenCodeClient:
147
154
  return OpenCodeApiProfile()
148
155
  return self._api_profile
149
156
 
157
+ @staticmethod
158
+ def _extract_max_text_chars(spec: dict[str, Any]) -> Optional[int]:
159
+ if not isinstance(spec, dict):
160
+ return None
161
+ components = spec.get("components")
162
+ if not isinstance(components, dict):
163
+ return None
164
+ schemas = components.get("schemas")
165
+ if not isinstance(schemas, dict):
166
+ return None
167
+ candidates: list[int] = []
168
+ for schema in schemas.values():
169
+ max_len = OpenCodeClient._find_text_max_length(schema)
170
+ if isinstance(max_len, int) and max_len > 0:
171
+ candidates.append(max_len)
172
+ return min(candidates) if candidates else None
173
+
174
+ @staticmethod
175
+ def _find_text_max_length(schema: Any) -> Optional[int]:
176
+ if not isinstance(schema, dict):
177
+ return None
178
+ candidates: list[int] = []
179
+ properties = schema.get("properties")
180
+ if isinstance(properties, dict) and "text" in properties:
181
+ text_schema = properties.get("text")
182
+ if isinstance(text_schema, dict):
183
+ max_len = text_schema.get("maxLength")
184
+ if isinstance(max_len, int) and max_len > 0:
185
+ candidates.append(max_len)
186
+ for key in ("allOf", "anyOf", "oneOf"):
187
+ seq = schema.get(key)
188
+ if isinstance(seq, list):
189
+ for item in seq:
190
+ item_len = OpenCodeClient._find_text_max_length(item)
191
+ if isinstance(item_len, int) and item_len > 0:
192
+ candidates.append(item_len)
193
+ return min(candidates) if candidates else None
194
+
195
+ def set_max_text_chars(self, value: Optional[int]) -> None:
196
+ self._max_text_chars_override = int(value) if isinstance(value, int) else None
197
+ self._max_text_chars_cache = None
198
+
199
+ async def _resolve_max_text_chars(
200
+ self, profile: Optional[OpenCodeApiProfile] = None
201
+ ) -> Optional[int]:
202
+ if self._max_text_chars_cache is not None:
203
+ return self._max_text_chars_cache
204
+ if profile is None:
205
+ profile = await self.detect_api_shape()
206
+ detected = (
207
+ profile.max_text_chars
208
+ if isinstance(profile.max_text_chars, int) and profile.max_text_chars > 0
209
+ else None
210
+ )
211
+ override = (
212
+ self._max_text_chars_override
213
+ if isinstance(self._max_text_chars_override, int)
214
+ and self._max_text_chars_override > 0
215
+ else None
216
+ )
217
+ if override is None:
218
+ resolved = detected
219
+ elif detected is None:
220
+ resolved = override
221
+ else:
222
+ resolved = min(override, detected)
223
+ self._max_text_chars_cache = resolved
224
+ return resolved
225
+
226
+ @staticmethod
227
+ def _split_text(text: str, max_chars: int) -> list[str]:
228
+ if max_chars <= 0 or len(text) <= max_chars:
229
+ return [text]
230
+ parts: list[str] = []
231
+ start = 0
232
+ length = len(text)
233
+ while start < length:
234
+ end = min(start + max_chars, length)
235
+ if end < length:
236
+ split = text.rfind("\n", start, end)
237
+ if split <= start:
238
+ split = text.rfind(" ", start, end)
239
+ if split > start:
240
+ end = split + 1
241
+ parts.append(text[start:end])
242
+ start = end
243
+ return [part for part in parts if part]
244
+
245
+ async def _build_text_parts(
246
+ self, message: str, profile: Optional[OpenCodeApiProfile] = None
247
+ ) -> list[dict[str, str]]:
248
+ limit = await self._resolve_max_text_chars(profile)
249
+ if limit is None:
250
+ return [{"type": "text", "text": message}]
251
+ chunks = self._split_text(message, limit)
252
+ return [{"type": "text", "text": chunk} for chunk in chunks]
253
+
150
254
  def _dir_params(self, directory: Optional[str]) -> dict[str, str]:
151
255
  return {"directory": directory} if directory else {}
152
256
 
@@ -275,8 +379,10 @@ class OpenCodeClient:
275
379
  model: Optional[dict[str, str]] = None,
276
380
  variant: Optional[str] = None,
277
381
  ) -> Any:
382
+ profile = await self.detect_api_shape()
383
+ parts = await self._build_text_parts(message, profile)
278
384
  payload: dict[str, Any] = {
279
- "parts": [{"type": "text", "text": message}],
385
+ "parts": parts,
280
386
  }
281
387
  if agent:
282
388
  payload["agent"] = agent
@@ -300,8 +406,10 @@ class OpenCodeClient:
300
406
  model: Optional[dict[str, str]] = None,
301
407
  variant: Optional[str] = None,
302
408
  ) -> Any:
409
+ profile = await self.detect_api_shape()
410
+ parts = await self._build_text_parts(message, profile)
303
411
  payload: dict[str, Any] = {
304
- "parts": [{"type": "text", "text": message}],
412
+ "parts": parts,
305
413
  }
306
414
  if agent:
307
415
  payload["agent"] = agent
@@ -310,7 +418,6 @@ class OpenCodeClient:
310
418
  if variant:
311
419
  payload["variant"] = variant
312
420
 
313
- profile = await self.detect_api_shape()
314
421
  if profile.supports_prompt_async:
315
422
  return await self._request(
316
423
  "POST",
@@ -335,8 +442,10 @@ class OpenCodeClient:
335
442
  model: Optional[dict[str, str]] = None,
336
443
  variant: Optional[str] = None,
337
444
  ) -> Any:
445
+ profile = await self.detect_api_shape()
446
+ parts = await self._build_text_parts(message, profile)
338
447
  payload: dict[str, Any] = {
339
- "parts": [{"type": "text", "text": message}],
448
+ "parts": parts,
340
449
  }
341
450
  if agent:
342
451
  payload["agent"] = agent
@@ -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: