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.
- codex_autorunner-1.1.0/PKG-INFO +154 -0
- codex_autorunner-1.1.0/README.md +90 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/pyproject.toml +6 -1
- codex_autorunner-1.1.0/src/codex_autorunner/__init__.py +14 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/codex/harness.py +1 -1
- codex_autorunner-1.1.0/src/codex_autorunner/agents/opencode/constants.py +3 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/opencode/harness.py +6 -1
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/opencode/runtime.py +59 -18
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/registry.py +22 -3
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/bootstrap.py +7 -3
- codex_autorunner-1.1.0/src/codex_autorunner/cli.py +8 -0
- codex_autorunner-1.1.0/src/codex_autorunner/codex_cli.py +20 -0
- codex_autorunner-1.1.0/src/codex_autorunner/core/__init__.py +5 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/about_car.py +6 -1
- codex_autorunner-1.1.0/src/codex_autorunner/core/app_server_ids.py +59 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/app_server_threads.py +11 -2
- 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
- codex_autorunner-1.1.0/src/codex_autorunner/core/archive.py +349 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/codex_runner.py +6 -2
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/config.py +197 -3
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/drafts.py +58 -4
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/engine.py +1329 -680
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/exceptions.py +4 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/flows/controller.py +25 -1
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/flows/models.py +13 -0
- codex_autorunner-1.1.0/src/codex_autorunner/core/flows/reasons.py +52 -0
- codex_autorunner-1.1.0/src/codex_autorunner/core/flows/reconciler.py +131 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/flows/runtime.py +35 -4
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/flows/store.py +83 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/flows/transition.py +5 -0
- codex_autorunner-1.1.0/src/codex_autorunner/core/flows/ux_helpers.py +257 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/git_utils.py +62 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/hub.py +121 -7
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/notifications.py +14 -2
- {codex_autorunner-1.0.0/src/codex_autorunner/integrations/agents → codex_autorunner-1.1.0/src/codex_autorunner/core/ports}/__init__.py +6 -5
- {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
- codex_autorunner-1.1.0/src/codex_autorunner/core/ports/backend_orchestrator.py +41 -0
- {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
- codex_autorunner-1.1.0/src/codex_autorunner/core/state_roots.py +57 -0
- codex_autorunner-1.1.0/src/codex_autorunner/core/supervisor_protocol.py +15 -0
- codex_autorunner-1.1.0/src/codex_autorunner/core/text_delta_coalescer.py +97 -0
- codex_autorunner-1.1.0/src/codex_autorunner/core/ticket_linter_cli.py +201 -0
- codex_autorunner-1.1.0/src/codex_autorunner/core/ticket_manager_cli.py +432 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/update.py +4 -5
- codex_autorunner-1.1.0/src/codex_autorunner/core/update_paths.py +28 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/usage.py +164 -12
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/utils.py +91 -9
- codex_autorunner-1.1.0/src/codex_autorunner/flows/review/__init__.py +17 -0
- 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
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/flows/ticket_flow/definition.py +9 -2
- codex_autorunner-1.1.0/src/codex_autorunner/integrations/agents/__init__.py +17 -0
- codex_autorunner-1.1.0/src/codex_autorunner/integrations/agents/backend_orchestrator.py +284 -0
- codex_autorunner-1.1.0/src/codex_autorunner/integrations/agents/codex_adapter.py +90 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/agents/codex_backend.py +158 -17
- codex_autorunner-1.1.0/src/codex_autorunner/integrations/agents/opencode_adapter.py +108 -0
- codex_autorunner-1.1.0/src/codex_autorunner/integrations/agents/opencode_backend.py +598 -0
- codex_autorunner-1.1.0/src/codex_autorunner/integrations/agents/runner.py +91 -0
- codex_autorunner-1.1.0/src/codex_autorunner/integrations/agents/wiring.py +271 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/app_server/client.py +7 -60
- codex_autorunner-1.1.0/src/codex_autorunner/integrations/app_server/env.py +5 -0
- 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
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/adapter.py +65 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/config.py +46 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/constants.py +1 -1
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/callbacks.py +7 -0
- codex_autorunner-1.1.0/src/codex_autorunner/integrations/telegram/handlers/commands/flows.py +1364 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/commands_runtime.py +4 -3
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/commands_spec.py +8 -2
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/messages.py +1 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/selections.py +61 -1
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/helpers.py +24 -1
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/service.py +15 -10
- codex_autorunner-1.1.0/src/codex_autorunner/integrations/telegram/ticket_flow_bridge.py +611 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/transport.py +3 -1
- codex_autorunner-1.1.0/src/codex_autorunner/routes/__init__.py +37 -0
- codex_autorunner-1.1.0/src/codex_autorunner/routes/agents.py +3 -0
- codex_autorunner-1.1.0/src/codex_autorunner/routes/analytics.py +3 -0
- codex_autorunner-1.1.0/src/codex_autorunner/routes/app_server.py +3 -0
- codex_autorunner-1.1.0/src/codex_autorunner/routes/base.py +3 -0
- codex_autorunner-1.1.0/src/codex_autorunner/routes/file_chat.py +7 -0
- codex_autorunner-1.1.0/src/codex_autorunner/routes/flows.py +7 -0
- codex_autorunner-1.1.0/src/codex_autorunner/routes/messages.py +7 -0
- codex_autorunner-1.1.0/src/codex_autorunner/routes/repos.py +3 -0
- codex_autorunner-1.1.0/src/codex_autorunner/routes/review.py +3 -0
- codex_autorunner-1.1.0/src/codex_autorunner/routes/sessions.py +3 -0
- codex_autorunner-1.1.0/src/codex_autorunner/routes/settings.py +3 -0
- codex_autorunner-1.1.0/src/codex_autorunner/routes/shared.py +3 -0
- codex_autorunner-1.1.0/src/codex_autorunner/routes/system.py +7 -0
- codex_autorunner-1.1.0/src/codex_autorunner/routes/usage.py +3 -0
- codex_autorunner-1.1.0/src/codex_autorunner/routes/voice.py +3 -0
- codex_autorunner-1.1.0/src/codex_autorunner/routes/workspace.py +3 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/server.py +2 -2
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/agentControls.js +40 -11
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/app.js +11 -3
- codex_autorunner-1.1.0/src/codex_autorunner/static/archive.js +826 -0
- codex_autorunner-1.1.0/src/codex_autorunner/static/archiveApi.js +37 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/autoRefresh.js +7 -7
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/dashboard.js +224 -171
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/hub.js +112 -94
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/index.html +80 -33
- codex_autorunner-1.1.0/src/codex_autorunner/static/messages.js +873 -0
- codex_autorunner-1.1.0/src/codex_autorunner/static/preserve.js +17 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/settings.js +125 -6
- codex_autorunner-1.1.0/src/codex_autorunner/static/smartRefresh.js +52 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/styles.css +1373 -101
- codex_autorunner-1.1.0/src/codex_autorunner/static/tabs.js +205 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/terminal.js +18 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/ticketEditor.js +99 -5
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/tickets.js +760 -87
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/utils.js +11 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/workspace.js +133 -40
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/workspaceFileBrowser.js +9 -9
- codex_autorunner-1.1.0/src/codex_autorunner/surfaces/__init__.py +5 -0
- codex_autorunner-1.1.0/src/codex_autorunner/surfaces/cli/__init__.py +6 -0
- {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/cli}/cli.py +73 -26
- codex_autorunner-1.1.0/src/codex_autorunner/surfaces/cli/codex_cli.py +20 -0
- codex_autorunner-1.1.0/src/codex_autorunner/surfaces/telegram/__init__.py +3 -0
- {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces}/web/app.py +97 -28
- {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces}/web/hub_jobs.py +2 -2
- {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces}/web/middleware.py +3 -3
- codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web/review.py +6 -0
- {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/__init__.py +2 -0
- {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/agents.py +4 -4
- {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/analytics.py +44 -6
- {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/app_server.py +4 -4
- codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web/routes/archive.py +357 -0
- {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/base.py +26 -8
- {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/file_chat.py +7 -7
- {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/flows.py +291 -107
- {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/messages.py +6 -6
- {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/repos.py +3 -3
- {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/review.py +2 -2
- {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/sessions.py +2 -2
- {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/settings.py +2 -2
- {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/shared.py +8 -4
- {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/system.py +8 -8
- {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/usage.py +4 -2
- {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/voice.py +1 -1
- {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/workspace.py +11 -11
- {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces}/web/runner_manager.py +2 -2
- {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces}/web/schemas.py +40 -0
- {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces}/web/static_assets.py +48 -2
- {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces}/web/static_refresh.py +1 -1
- {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces}/web/terminal_sessions.py +1 -1
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/tickets/__init__.py +8 -1
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/tickets/agent_pool.py +26 -4
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/tickets/files.py +6 -2
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/tickets/models.py +3 -1
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/tickets/outbox.py +12 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/tickets/runner.py +63 -5
- codex_autorunner-1.1.0/src/codex_autorunner/web/__init__.py +5 -0
- codex_autorunner-1.1.0/src/codex_autorunner/web/app.py +3 -0
- codex_autorunner-1.1.0/src/codex_autorunner/web/hub_jobs.py +3 -0
- codex_autorunner-1.1.0/src/codex_autorunner/web/middleware.py +3 -0
- codex_autorunner-1.1.0/src/codex_autorunner/web/pty_session.py +3 -0
- codex_autorunner-1.1.0/src/codex_autorunner/web/runner_manager.py +3 -0
- codex_autorunner-1.1.0/src/codex_autorunner/web/schemas.py +3 -0
- codex_autorunner-1.1.0/src/codex_autorunner/web/static_assets.py +7 -0
- codex_autorunner-1.1.0/src/codex_autorunner/web/static_refresh.py +3 -0
- codex_autorunner-1.1.0/src/codex_autorunner/web/terminal_sessions.py +3 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/workspace/paths.py +49 -33
- codex_autorunner-1.1.0/src/codex_autorunner.egg-info/PKG-INFO +154 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner.egg-info/SOURCES.txt +76 -6
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_about_car_terminal_context.py +1 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_agent_run_events.py +3 -3
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_agents_registry.py +53 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_api_contract.py +5 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_app_server_events.py +1 -1
- codex_autorunner-1.1.0/tests/test_archive_worktree.py +121 -0
- codex_autorunner-1.1.0/tests/test_engine_app_server.py +198 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_engine_end_review.py +1 -1
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_hub_create.py +19 -3
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_hub_supervisor.py +25 -4
- codex_autorunner-1.1.0/tests/test_opencode_agent_pool.py +120 -0
- codex_autorunner-1.1.0/tests/test_opencode_backend_streaming.py +128 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_opencode_runtime.py +33 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_review_service.py +3 -3
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_adapter.py +10 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_bot_config.py +49 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_cache_cleanup.py +10 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_command_registry.py +9 -0
- codex_autorunner-1.1.0/tests/test_telegram_flow_aliases.py +75 -0
- codex_autorunner-1.1.0/tests/test_telegram_flow_bootstrap.py +172 -0
- codex_autorunner-1.1.0/tests/test_telegram_flow_callback_actions.py +167 -0
- codex_autorunner-1.1.0/tests/test_telegram_flow_commands.py +22 -0
- codex_autorunner-1.1.0/tests/test_telegram_flow_lifecycle.py +206 -0
- codex_autorunner-1.1.0/tests/test_telegram_flow_status.py +191 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_handlers_callbacks.py +49 -0
- codex_autorunner-1.1.0/tests/test_telegram_ticket_flow_bridge.py +190 -0
- codex_autorunner-1.1.0/tests/test_ticket_linter_cli.py +93 -0
- codex_autorunner-1.1.0/tests/test_ticket_manager_cli.py +65 -0
- codex_autorunner-1.1.0/tests/test_update_paths.py +28 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_usage.py +94 -0
- codex_autorunner-1.1.0/tests/test_workspace_paths.py +89 -0
- codex_autorunner-1.0.0/PKG-INFO +0 -246
- codex_autorunner-1.0.0/README.md +0 -182
- codex_autorunner-1.0.0/src/codex_autorunner/__init__.py +0 -3
- codex_autorunner-1.0.0/src/codex_autorunner/codex_cli.py +0 -84
- codex_autorunner-1.0.0/src/codex_autorunner/core/__init__.py +0 -1
- codex_autorunner-1.0.0/src/codex_autorunner/core/static_assets.py +0 -55
- codex_autorunner-1.0.0/src/codex_autorunner/core/text_delta_coalescer.py +0 -43
- codex_autorunner-1.0.0/src/codex_autorunner/integrations/agents/opencode_backend.py +0 -325
- codex_autorunner-1.0.0/src/codex_autorunner/integrations/telegram/handlers/commands/flows.py +0 -227
- codex_autorunner-1.0.0/src/codex_autorunner/integrations/telegram/ticket_flow_bridge.py +0 -322
- codex_autorunner-1.0.0/src/codex_autorunner/static/messages.js +0 -470
- codex_autorunner-1.0.0/src/codex_autorunner/static/tabs.js +0 -64
- codex_autorunner-1.0.0/src/codex_autorunner.egg-info/PKG-INFO +0 -246
- codex_autorunner-1.0.0/tests/test_engine_app_server.py +0 -161
- codex_autorunner-1.0.0/tests/test_workspace_paths.py +0 -42
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/LICENSE +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/setup.cfg +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/__main__.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/__init__.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/base.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/codex/__init__.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/opencode/__init__.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/opencode/agent_config.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/opencode/client.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/opencode/events.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/opencode/logging.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/opencode/run_prompt.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/opencode/supervisor.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/types.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/api.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/codex_runner.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/adapter_utils.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/app_server_logging.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/app_server_prompts.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/circuit_breaker.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/docs.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/flows/__init__.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/flows/definition.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/flows/worker_process.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/injected_context.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/locks.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/logging_utils.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/optional_dependencies.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/patch_utils.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/path_utils.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/prompt.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/prompts.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/redaction.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/request_context.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/retry.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/review_context.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/run_index.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/runner_controller.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/runner_process.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/sqlite_utils.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/state.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/supervisor_utils.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/core/update_runner.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/discovery.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/flows/ticket_flow/__init__.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/housekeeping.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/__init__.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/app_server/__init__.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/app_server/supervisor.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/github/__init__.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/github/service.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/__init__.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/api_schemas.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/commands_registry.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/dispatch.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/doctor.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/__init__.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/approvals.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/commands/__init__.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/commands/approvals.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/commands/execution.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/commands/files.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/commands/formatting.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/commands/github.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/commands/shared.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/commands/voice.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/commands/workspace.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/questions.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/handlers/utils.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/notifications.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/outbox.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/overflow.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/progress_stream.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/rendering.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/retry.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/runtime.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/state.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/trigger_mode.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/types.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/integrations/telegram/voice.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/manifest.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/plugin_api.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/agentEvents.js +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/bootstrap.js +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/bus.js +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/cache.js +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/constants.js +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/diffRenderer.js +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/docChatCore.js +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/docChatStorage.js +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/docChatVoice.js +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/docEditor.js +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/env.js +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/eventSummarizer.js +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/fileChat.js +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/health.js +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/liveUpdates.js +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/loader.js +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/mobileCompact.js +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/terminalManager.js +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/ticketChatActions.js +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/ticketChatEvents.js +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/ticketChatStorage.js +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/ticketChatStream.js +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/ticketVoice.js +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/LICENSE.xterm +0 -0
- {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
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-400-cyrillic.woff2 +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-400-greek.woff2 +0 -0
- {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
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-400-latin.woff2 +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-400-vietnamese.woff2 +0 -0
- {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
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-500-cyrillic.woff2 +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-500-greek.woff2 +0 -0
- {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
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-500-latin.woff2 +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-500-vietnamese.woff2 +0 -0
- {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
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-600-cyrillic.woff2 +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-600-greek.woff2 +0 -0
- {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
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-600-latin.woff2 +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/JetBrainsMono-600-vietnamese.woff2 +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/fonts/jetbrains-mono/OFL.txt +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/xterm-addon-fit.js +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/xterm.css +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/vendor/xterm.js +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/voice.js +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/static/workspaceApi.js +0 -0
- {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces}/web/__init__.py +0 -0
- {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces}/web/pty_session.py +0 -0
- {codex_autorunner-1.0.0/src/codex_autorunner → codex_autorunner-1.1.0/src/codex_autorunner/surfaces/web}/routes/terminal_images.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/tickets/frontmatter.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/tickets/lint.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/tickets/replies.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/tickets/spec_ingest.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/voice/__init__.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/voice/capture.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/voice/config.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/voice/provider.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/voice/providers/__init__.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/voice/providers/openai_whisper.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/voice/resolver.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/voice/service.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/workspace/__init__.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner.egg-info/dependency_links.txt +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner.egg-info/entry_points.txt +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner.egg-info/requires.txt +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner.egg-info/top_level.txt +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_agents_plugins.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_app_server_client.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_app_server_event_formatter.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_app_server_prompts.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_app_server_supervisor.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_app_server_thread_registry.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_auth_middleware.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_base_path.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_base_path_static.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_cli_init.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_cli_sessions.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_cli_status.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_codex_app_server_integration.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_codex_cli_flags.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_codex_runner.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_config_resolution.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_core_web_boundary.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_engine_logs.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_file_chat_drafts.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_housekeeping.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_hub_foundation.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_hub_terminal_sessions.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_hub_ui_escape.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_lock_utils.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_logging_utils.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_notifications.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_opencode_agent_config.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_opencode_client.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_opencode_event_formatter.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_opencode_integration.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_opencode_review_arguments.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_optional_dependencies.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_origin_middleware.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_patch_utils.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_prompt.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_redaction.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_request_logging.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_review_context.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_runner_controller.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_sse_streams.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_state_lock.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_state_sessions.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_static.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_static_asset_cache.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_system_update_check.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_system_update_worker.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_bot_integration.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_bot_lock.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_codex_feature_flags.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_fast_ack.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_handlers_messages.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_interrupt_status.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_media_batch_failure.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_opencode_context_cache.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_opencode_usage.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_outbox.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_overflow.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_paths_compatible.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_progress_stream.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_review_opencode.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_state.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_status_rate_limits.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_task_tracking.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_thread_paths.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_topic_queue.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_transport.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_trigger_mode.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_turn_queue.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_update_dedupe.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_telegram_whisper_disclaimer.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_terminal_idle_timeout.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_terminal_input_dedupe.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_ticket_flow_approval_config.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_voice_capture.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_voice_config.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_voice_service.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_voice_transcribe_endpoint.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_voice_ui.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_voice_whisper_mime_types.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_voice_whisper_provider.py +0 -0
- {codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/tests/test_workspace_functional.py +0 -0
- {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
|
+
[](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
|
+

|
|
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
|
+

|
|
132
|
+
|
|
133
|
+
Tickets are just markdown files that both you and the agent can edit.
|
|
134
|
+

|
|
135
|
+
|
|
136
|
+
You don't have to babysit the agents, they inbox you or ping you on Telegram.
|
|
137
|
+

|
|
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
|
+

|
|
141
|
+
|
|
142
|
+
All core workspace documents are also just markdown files, so you and the agent can easily edit them.
|
|
143
|
+

|
|
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
|
+

|
|
147
|
+

|
|
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
|
+

|
|
151
|
+

|
|
152
|
+
|
|
153
|
+
## Star history
|
|
154
|
+
[](https://star-history.com/#Git-on-my-level/codex-autorunner&Date)
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# CAR (codex-autorunner)
|
|
2
|
+
[](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
|
+

|
|
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
|
+

|
|
68
|
+
|
|
69
|
+
Tickets are just markdown files that both you and the agent can edit.
|
|
70
|
+

|
|
71
|
+
|
|
72
|
+
You don't have to babysit the agents, they inbox you or ping you on Telegram.
|
|
73
|
+

|
|
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
|
+

|
|
77
|
+
|
|
78
|
+
All core workspace documents are also just markdown files, so you and the agent can easily edit them.
|
|
79
|
+

|
|
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
|
+

|
|
83
|
+

|
|
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
|
+

|
|
87
|
+

|
|
88
|
+
|
|
89
|
+
## Star history
|
|
90
|
+
[](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.
|
|
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"
|
{codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/codex/harness.py
RENAMED
|
@@ -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 ...
|
|
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
|
{codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/opencode/harness.py
RENAMED
|
@@ -6,9 +6,10 @@ import logging
|
|
|
6
6
|
from pathlib import Path
|
|
7
7
|
from typing import Any, AsyncIterator, Optional
|
|
8
8
|
|
|
9
|
-
from ...
|
|
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:
|
{codex_autorunner-1.0.0 → codex_autorunner-1.1.0}/src/codex_autorunner/agents/opencode/runtime.py
RENAMED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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)
|
|
180
|
+
"Ignoring agent plugin %s (api_version=%s) requires newer core (%s)",
|
|
169
181
|
agent_id,
|
|
170
|
-
|
|
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 ""
|
|
24
|
+
return ""
|
|
23
25
|
|
|
24
26
|
|
|
25
27
|
def sample_spec() -> str:
|
|
26
|
-
return ""
|
|
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, "
|
|
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,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
|
+
]
|
|
@@ -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
|
|
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"
|