codex-autorunner 1.1.0__py3-none-any.whl → 1.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. codex_autorunner/agents/opencode/client.py +113 -4
  2. codex_autorunner/agents/opencode/supervisor.py +4 -0
  3. codex_autorunner/agents/registry.py +17 -7
  4. codex_autorunner/bootstrap.py +219 -1
  5. codex_autorunner/core/__init__.py +17 -1
  6. codex_autorunner/core/about_car.py +114 -1
  7. codex_autorunner/core/app_server_threads.py +6 -0
  8. codex_autorunner/core/config.py +236 -1
  9. codex_autorunner/core/context_awareness.py +38 -0
  10. codex_autorunner/core/docs.py +0 -122
  11. codex_autorunner/core/filebox.py +265 -0
  12. codex_autorunner/core/flows/controller.py +71 -1
  13. codex_autorunner/core/flows/reconciler.py +4 -1
  14. codex_autorunner/core/flows/runtime.py +22 -0
  15. codex_autorunner/core/flows/store.py +61 -9
  16. codex_autorunner/core/flows/transition.py +23 -16
  17. codex_autorunner/core/flows/ux_helpers.py +18 -3
  18. codex_autorunner/core/flows/worker_process.py +32 -6
  19. codex_autorunner/core/hub.py +198 -41
  20. codex_autorunner/core/lifecycle_events.py +253 -0
  21. codex_autorunner/core/path_utils.py +2 -1
  22. codex_autorunner/core/pma_audit.py +224 -0
  23. codex_autorunner/core/pma_context.py +496 -0
  24. codex_autorunner/core/pma_dispatch_interceptor.py +284 -0
  25. codex_autorunner/core/pma_lifecycle.py +527 -0
  26. codex_autorunner/core/pma_queue.py +367 -0
  27. codex_autorunner/core/pma_safety.py +221 -0
  28. codex_autorunner/core/pma_state.py +115 -0
  29. codex_autorunner/core/ports/agent_backend.py +2 -5
  30. codex_autorunner/core/ports/run_event.py +1 -4
  31. codex_autorunner/core/prompt.py +0 -80
  32. codex_autorunner/core/prompts.py +56 -172
  33. codex_autorunner/core/redaction.py +0 -4
  34. codex_autorunner/core/review_context.py +11 -9
  35. codex_autorunner/core/runner_controller.py +35 -33
  36. codex_autorunner/core/runner_state.py +147 -0
  37. codex_autorunner/core/runtime.py +829 -0
  38. codex_autorunner/core/sqlite_utils.py +13 -4
  39. codex_autorunner/core/state.py +7 -10
  40. codex_autorunner/core/state_roots.py +5 -0
  41. codex_autorunner/core/templates/__init__.py +39 -0
  42. codex_autorunner/core/templates/git_mirror.py +234 -0
  43. codex_autorunner/core/templates/provenance.py +56 -0
  44. codex_autorunner/core/templates/scan_cache.py +120 -0
  45. codex_autorunner/core/ticket_linter_cli.py +17 -0
  46. codex_autorunner/core/ticket_manager_cli.py +154 -92
  47. codex_autorunner/core/time_utils.py +11 -0
  48. codex_autorunner/core/types.py +18 -0
  49. codex_autorunner/core/utils.py +34 -6
  50. codex_autorunner/flows/review/service.py +23 -25
  51. codex_autorunner/flows/ticket_flow/definition.py +43 -1
  52. codex_autorunner/integrations/agents/__init__.py +2 -0
  53. codex_autorunner/integrations/agents/backend_orchestrator.py +18 -0
  54. codex_autorunner/integrations/agents/codex_backend.py +19 -8
  55. codex_autorunner/integrations/agents/runner.py +3 -8
  56. codex_autorunner/integrations/agents/wiring.py +8 -0
  57. codex_autorunner/integrations/telegram/doctor.py +228 -6
  58. codex_autorunner/integrations/telegram/handlers/commands/execution.py +236 -74
  59. codex_autorunner/integrations/telegram/handlers/commands/files.py +314 -75
  60. codex_autorunner/integrations/telegram/handlers/commands/flows.py +346 -58
  61. codex_autorunner/integrations/telegram/handlers/commands/workspace.py +498 -37
  62. codex_autorunner/integrations/telegram/handlers/commands_runtime.py +202 -45
  63. codex_autorunner/integrations/telegram/handlers/commands_spec.py +18 -7
  64. codex_autorunner/integrations/telegram/handlers/messages.py +26 -1
  65. codex_autorunner/integrations/telegram/helpers.py +1 -3
  66. codex_autorunner/integrations/telegram/runtime.py +9 -4
  67. codex_autorunner/integrations/telegram/service.py +30 -0
  68. codex_autorunner/integrations/telegram/state.py +38 -0
  69. codex_autorunner/integrations/telegram/ticket_flow_bridge.py +10 -4
  70. codex_autorunner/integrations/telegram/transport.py +10 -3
  71. codex_autorunner/integrations/templates/__init__.py +27 -0
  72. codex_autorunner/integrations/templates/scan_agent.py +312 -0
  73. codex_autorunner/server.py +2 -2
  74. codex_autorunner/static/agentControls.js +21 -5
  75. codex_autorunner/static/app.js +115 -11
  76. codex_autorunner/static/chatUploads.js +137 -0
  77. codex_autorunner/static/docChatCore.js +185 -13
  78. codex_autorunner/static/fileChat.js +68 -40
  79. codex_autorunner/static/fileboxUi.js +159 -0
  80. codex_autorunner/static/hub.js +46 -81
  81. codex_autorunner/static/index.html +303 -24
  82. codex_autorunner/static/messages.js +82 -4
  83. codex_autorunner/static/notifications.js +255 -0
  84. codex_autorunner/static/pma.js +1167 -0
  85. codex_autorunner/static/settings.js +3 -0
  86. codex_autorunner/static/streamUtils.js +57 -0
  87. codex_autorunner/static/styles.css +9125 -6742
  88. codex_autorunner/static/templateReposSettings.js +225 -0
  89. codex_autorunner/static/ticketChatActions.js +165 -3
  90. codex_autorunner/static/ticketChatStream.js +17 -119
  91. codex_autorunner/static/ticketEditor.js +41 -13
  92. codex_autorunner/static/ticketTemplates.js +798 -0
  93. codex_autorunner/static/tickets.js +69 -19
  94. codex_autorunner/static/turnEvents.js +27 -0
  95. codex_autorunner/static/turnResume.js +33 -0
  96. codex_autorunner/static/utils.js +28 -0
  97. codex_autorunner/static/workspace.js +258 -44
  98. codex_autorunner/static/workspaceFileBrowser.js +6 -4
  99. codex_autorunner/surfaces/cli/cli.py +1465 -155
  100. codex_autorunner/surfaces/cli/pma_cli.py +817 -0
  101. codex_autorunner/surfaces/web/app.py +253 -49
  102. codex_autorunner/surfaces/web/routes/__init__.py +4 -0
  103. codex_autorunner/surfaces/web/routes/analytics.py +29 -22
  104. codex_autorunner/surfaces/web/routes/file_chat.py +317 -36
  105. codex_autorunner/surfaces/web/routes/filebox.py +227 -0
  106. codex_autorunner/surfaces/web/routes/flows.py +219 -29
  107. codex_autorunner/surfaces/web/routes/messages.py +70 -39
  108. codex_autorunner/surfaces/web/routes/pma.py +1652 -0
  109. codex_autorunner/surfaces/web/routes/repos.py +1 -1
  110. codex_autorunner/surfaces/web/routes/shared.py +0 -3
  111. codex_autorunner/surfaces/web/routes/templates.py +634 -0
  112. codex_autorunner/surfaces/web/runner_manager.py +2 -2
  113. codex_autorunner/surfaces/web/schemas.py +70 -18
  114. codex_autorunner/tickets/agent_pool.py +27 -0
  115. codex_autorunner/tickets/files.py +33 -16
  116. codex_autorunner/tickets/lint.py +50 -0
  117. codex_autorunner/tickets/models.py +3 -0
  118. codex_autorunner/tickets/outbox.py +41 -5
  119. codex_autorunner/tickets/runner.py +350 -69
  120. {codex_autorunner-1.1.0.dist-info → codex_autorunner-1.2.0.dist-info}/METADATA +15 -19
  121. {codex_autorunner-1.1.0.dist-info → codex_autorunner-1.2.0.dist-info}/RECORD +125 -94
  122. codex_autorunner/core/adapter_utils.py +0 -21
  123. codex_autorunner/core/engine.py +0 -3302
  124. {codex_autorunner-1.1.0.dist-info → codex_autorunner-1.2.0.dist-info}/WHEEL +0 -0
  125. {codex_autorunner-1.1.0.dist-info → codex_autorunner-1.2.0.dist-info}/entry_points.txt +0 -0
  126. {codex_autorunner-1.1.0.dist-info → codex_autorunner-1.2.0.dist-info}/licenses/LICENSE +0 -0
  127. {codex_autorunner-1.1.0.dist-info → codex_autorunner-1.2.0.dist-info}/top_level.txt +0 -0
@@ -2,14 +2,16 @@
2
2
  /**
3
3
  * Ticket Editor Modal - handles creating, editing, and deleting tickets
4
4
  */
5
- import { api, flash, updateUrlParams, splitMarkdownFrontmatter } from "./utils.js";
5
+ import { api, confirmModal, flash, updateUrlParams, splitMarkdownFrontmatter } from "./utils.js";
6
6
  import { publish } from "./bus.js";
7
7
  import { clearTicketChatHistory } from "./ticketChatStorage.js";
8
- import { setTicketIndex, sendTicketChat, cancelTicketChat, applyTicketPatch, discardTicketPatch, loadTicketPending, renderTicketChat, resetTicketChatState, ticketChatState, } from "./ticketChatActions.js";
8
+ import { setTicketIndex, sendTicketChat, cancelTicketChat, applyTicketPatch, discardTicketPatch, loadTicketPending, renderTicketChat, resetTicketChatState, ticketChatState, resumeTicketPendingTurn, } from "./ticketChatActions.js";
9
9
  import { initAgentControls } from "./agentControls.js";
10
10
  import { initTicketVoice } from "./ticketVoice.js";
11
11
  import { initTicketChatEvents, renderTicketEvents, renderTicketMessages } from "./ticketChatEvents.js";
12
+ import { initChatPasteUpload } from "./chatUploads.js";
12
13
  import { DocEditor } from "./docEditor.js";
14
+ import { initTicketTemplates } from "./ticketTemplates.js";
13
15
  const DEFAULT_FRONTMATTER = {
14
16
  agent: "codex",
15
17
  done: false,
@@ -88,7 +90,13 @@ async function navigateTicket(delta) {
88
90
  const idx = list.findIndex((ticket) => ticket.index === state.ticketIndex);
89
91
  const target = idx >= 0 ? list[idx + delta] : null;
90
92
  if (target && target.index != null) {
91
- openTicketEditor(target);
93
+ try {
94
+ const data = (await api(`/api/flows/ticket_flow/tickets/${target.index}`));
95
+ openTicketEditor(data);
96
+ }
97
+ catch (err) {
98
+ flash(`Failed to navigate to ticket: ${err.message}`, "error");
99
+ }
92
100
  }
93
101
  void updateTicketNavButtons();
94
102
  }
@@ -298,20 +306,24 @@ function extractFrontmatter(ticket) {
298
306
  /**
299
307
  * Build full markdown content from frontmatter form + body textarea
300
308
  */
309
+ function yamlQuote(value) {
310
+ // Use JSON.stringify for simple, safe double-quoted scalars (handles colons, quotes, newlines).
311
+ return JSON.stringify(value ?? "");
312
+ }
301
313
  function buildTicketContent() {
302
314
  const { content } = els();
303
315
  const fm = getFrontmatterFromForm();
304
316
  const body = content?.value || "";
305
- // Reconstruct frontmatter YAML
317
+ // Reconstruct frontmatter YAML with quoted scalars to tolerate special characters.
306
318
  const lines = ["---"];
307
- lines.push(`agent: ${fm.agent}`);
319
+ lines.push(`agent: ${yamlQuote(fm.agent)}`);
308
320
  lines.push(`done: ${fm.done}`);
309
321
  if (fm.title)
310
- lines.push(`title: ${fm.title}`);
322
+ lines.push(`title: ${yamlQuote(fm.title)}`);
311
323
  if (fm.model)
312
- lines.push(`model: ${fm.model}`);
324
+ lines.push(`model: ${yamlQuote(fm.model)}`);
313
325
  if (fm.reasoning)
314
- lines.push(`reasoning: ${fm.reasoning}`);
326
+ lines.push(`reasoning: ${yamlQuote(fm.reasoning)}`);
315
327
  lines.push("---");
316
328
  lines.push("");
317
329
  lines.push(body);
@@ -478,8 +490,12 @@ async function performAutosave() {
478
490
  // Notify that tickets changed
479
491
  publish("tickets:updated", {});
480
492
  }
481
- catch {
493
+ catch (err) {
494
+ // Surface the failure to the user and let DocEditor keep the "dirty" state
495
+ // so a retry is attempted instead of falsely reporting success.
482
496
  setAutosaveStatus("error");
497
+ flash(err?.message || "Failed to save ticket", "error");
498
+ throw err;
483
499
  }
484
500
  }
485
501
  /**
@@ -590,6 +606,7 @@ export function openTicketEditor(ticket) {
590
606
  renderTicketChat();
591
607
  renderTicketEvents();
592
608
  renderTicketMessages();
609
+ void resumeTicketPendingTurn(ticket?.index ?? null);
593
610
  state.isOpen = true;
594
611
  modal.classList.remove("hidden");
595
612
  // Update URL with ticket index
@@ -614,7 +631,9 @@ export function closeTicketEditor() {
614
631
  return;
615
632
  // Autosave on close if there are changes
616
633
  if (hasUnsavedChanges()) {
617
- void performAutosave();
634
+ // Fire-and-forget: swallow rejection because the error is already flashed
635
+ // inside performAutosave and DocEditor keeps the buffer dirty for retry.
636
+ void performAutosave().catch(() => { });
618
637
  }
619
638
  // Cancel any running chat
620
639
  if (ticketChatState.status === "running") {
@@ -654,7 +673,7 @@ export async function deleteTicket() {
654
673
  flash("Cannot delete: no ticket selected", "error");
655
674
  return;
656
675
  }
657
- const confirmed = window.confirm(`Delete TICKET-${String(state.ticketIndex).padStart(3, "0")}.md? This cannot be undone.`);
676
+ const confirmed = await confirmModal(`Delete TICKET-${String(state.ticketIndex).padStart(3, "0")}.md? This cannot be undone.`);
658
677
  if (!confirmed)
659
678
  return;
660
679
  setButtonsLoading(true);
@@ -703,6 +722,8 @@ export function initTicketEditor() {
703
722
  void initTicketVoice();
704
723
  // Initialize rich chat experience (events toggle, etc.)
705
724
  initTicketChatEvents();
725
+ // Initialize ticket templates picker
726
+ initTicketTemplates();
706
727
  // Button handlers
707
728
  if (deleteBtn)
708
729
  deleteBtn.addEventListener("click", () => void deleteTicket());
@@ -772,6 +793,13 @@ export function initTicketEditor() {
772
793
  chatInput.style.height = "auto";
773
794
  chatInput.style.height = Math.min(chatInput.scrollHeight, 100) + "px";
774
795
  });
796
+ initChatPasteUpload({
797
+ textarea: chatInput,
798
+ basePath: "/api/filebox",
799
+ box: "inbox",
800
+ insertStyle: "both",
801
+ pathPrefix: ".codex-autorunner/filebox",
802
+ });
775
803
  }
776
804
  // Close on backdrop click
777
805
  modal.addEventListener("click", (e) => {
@@ -806,8 +834,8 @@ export function initTicketEditor() {
806
834
  // Don't interfere with typing
807
835
  if (isTypingTarget(e.target))
808
836
  return;
809
- // Only allow Alt or no modifier (no Ctrl/Meta/Shift)
810
- if (e.ctrlKey || e.metaKey || e.shiftKey)
837
+ // Require Alt modifier for navigation (no Ctrl/Meta/Shift)
838
+ if (!e.altKey || e.ctrlKey || e.metaKey || e.shiftKey)
811
839
  return;
812
840
  e.preventDefault();
813
841
  void navigateTicket(e.key === "ArrowLeft" ? -1 : 1);