codex-autorunner 1.2.0__py3-none-any.whl → 1.2.1__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.
@@ -8,6 +8,8 @@ let closeModalFn = null;
8
8
  let documentListenerInstalled = false;
9
9
  let modalElements = null;
10
10
  let isRefreshing = false;
11
+ const DROPDOWN_MARGIN = 8;
12
+ const DROPDOWN_OFFSET = 6;
11
13
  const NOTIFICATIONS_REFRESH_ID = "notifications";
12
14
  const NOTIFICATIONS_REFRESH_MS = 15000;
13
15
  function getModalElements() {
@@ -93,10 +95,40 @@ function closeDropdown() {
93
95
  if (!activeRoot)
94
96
  return;
95
97
  activeRoot.dropdown.classList.add("hidden");
98
+ activeRoot.dropdown.style.position = "";
99
+ activeRoot.dropdown.style.left = "";
100
+ activeRoot.dropdown.style.right = "";
101
+ activeRoot.dropdown.style.top = "";
102
+ activeRoot.dropdown.style.visibility = "";
96
103
  activeRoot.trigger.setAttribute("aria-expanded", "false");
97
104
  activeRoot = null;
98
105
  removeDocumentListener();
99
106
  }
107
+ function positionDropdown(root) {
108
+ const { trigger, dropdown } = root;
109
+ const triggerRect = trigger.getBoundingClientRect();
110
+ dropdown.style.position = "fixed";
111
+ dropdown.style.left = "0";
112
+ dropdown.style.right = "auto";
113
+ dropdown.style.top = "0";
114
+ dropdown.style.visibility = "hidden";
115
+ const dropdownRect = dropdown.getBoundingClientRect();
116
+ const width = dropdownRect.width || 240;
117
+ const height = dropdownRect.height || 0;
118
+ const viewportWidth = window.innerWidth;
119
+ const viewportHeight = window.innerHeight;
120
+ let left = triggerRect.right - width;
121
+ left = Math.min(Math.max(left, DROPDOWN_MARGIN), viewportWidth - width - DROPDOWN_MARGIN);
122
+ const preferredTop = triggerRect.bottom + DROPDOWN_OFFSET;
123
+ const fallbackTop = triggerRect.top - DROPDOWN_OFFSET - height;
124
+ let top = preferredTop;
125
+ if (preferredTop + height > viewportHeight - DROPDOWN_MARGIN) {
126
+ top = Math.max(DROPDOWN_MARGIN, fallbackTop);
127
+ }
128
+ dropdown.style.left = `${Math.max(DROPDOWN_MARGIN, left)}px`;
129
+ dropdown.style.top = `${Math.max(DROPDOWN_MARGIN, top)}px`;
130
+ dropdown.style.visibility = "";
131
+ }
100
132
  function openDropdown(root) {
101
133
  if (activeRoot && activeRoot !== root) {
102
134
  activeRoot.dropdown.classList.add("hidden");
@@ -105,6 +137,7 @@ function openDropdown(root) {
105
137
  activeRoot = root;
106
138
  renderDropdown(root);
107
139
  root.dropdown.classList.remove("hidden");
140
+ positionDropdown(root);
108
141
  root.trigger.setAttribute("aria-expanded", "true");
109
142
  installDocumentListener();
110
143
  }
@@ -10971,6 +10971,22 @@ button.filebox-delete:hover {
10971
10971
  min-height: 0;
10972
10972
  }
10973
10973
 
10974
+ .archive-list-section {
10975
+ display: grid;
10976
+ gap: 8px;
10977
+ }
10978
+
10979
+ .archive-list-header {
10980
+ text-transform: uppercase;
10981
+ letter-spacing: 0.08em;
10982
+ font-size: 10px;
10983
+ padding: 0 4px;
10984
+ }
10985
+
10986
+ .archive-list-empty {
10987
+ padding: 4px 6px;
10988
+ }
10989
+
10974
10990
  .archive-snapshot {
10975
10991
  text-align: left;
10976
10992
  border: 1px solid var(--border);
@@ -49,6 +49,17 @@ const CAR_CONTEXT_HINT = wrapInjectedContext(CONSTANTS.PROMPTS.CAR_CONTEXT_HINT)
49
49
  const VOICE_TRANSCRIPT_DISCLAIMER_TEXT = CONSTANTS.PROMPTS?.VOICE_TRANSCRIPT_DISCLAIMER ||
50
50
  "Note: transcribed from user voice. If confusing or possibly inaccurate and you cannot infer the intention please clarify before proceeding.";
51
51
  const INJECTED_CONTEXT_TAG_RE = /<injected context>/i;
52
+ const CAR_CONTEXT_COMMAND_RE = [
53
+ /^\/\S/,
54
+ /^\.\/\S/,
55
+ /^git(\s|$)/,
56
+ /^cd(\s|$)/,
57
+ /^ls(\s|$)/,
58
+ /^make(\s|$)/,
59
+ /^pnpm(\s|$)/,
60
+ /^npm(\s|$)/,
61
+ /^python3?(\s|$)/,
62
+ ];
52
63
  function wrapInjectedContext(text) {
53
64
  return `<injected context>\n${text}\n</injected context>`;
54
65
  }
@@ -57,6 +68,13 @@ function wrapInjectedContextIfNeeded(text) {
57
68
  return text;
58
69
  return INJECTED_CONTEXT_TAG_RE.test(text) ? text : wrapInjectedContext(text);
59
70
  }
71
+ function looksLikeCommand(text) {
72
+ const trimmed = text.trim();
73
+ if (!trimmed)
74
+ return false;
75
+ const lowered = trimmed.toLowerCase();
76
+ return CAR_CONTEXT_COMMAND_RE.some((pattern) => pattern.test(lowered));
77
+ }
60
78
  const LEGACY_SESSION_STORAGE_KEY = "codex_terminal_session_id";
61
79
  const SESSION_STORAGE_PREFIX = "codex_terminal_session_id:";
62
80
  const SESSION_STORAGE_TS_PREFIX = "codex_terminal_session_ts:";
@@ -620,12 +638,13 @@ export class TerminalManager {
620
638
  return null;
621
639
  if (manager._hasTextInputHookFired(CAR_CONTEXT_HOOK_ID))
622
640
  return null;
623
- const lowered = text.toLowerCase();
624
- const hit = CONSTANTS.KEYWORDS.CAR_CONTEXT.some((kw) => lowered.includes(kw));
625
- if (!hit)
641
+ if (looksLikeCommand(text))
626
642
  return null;
643
+ const lowered = text.toLowerCase();
627
644
  if (lowered.includes("about_car.md"))
628
645
  return null;
646
+ if (lowered.includes(".codex-autorunner"))
647
+ return null;
629
648
  if (text.includes(CONSTANTS.PROMPTS.CAR_CONTEXT_HINT) ||
630
649
  text.includes(CAR_CONTEXT_HINT)) {
631
650
  return null;
@@ -17,6 +17,8 @@ from ..schemas import (
17
17
  ArchiveSnapshotsResponse,
18
18
  ArchiveSnapshotSummary,
19
19
  ArchiveTreeResponse,
20
+ LocalRunArchivesResponse,
21
+ LocalRunArchiveSummary,
20
22
  )
21
23
 
22
24
  logger = logging.getLogger("codex_autorunner.routes.archive")
@@ -28,6 +30,10 @@ def _archive_worktrees_root(repo_root: Path) -> Path:
28
30
  return repo_root / ".codex-autorunner" / "archive" / "worktrees"
29
31
 
30
32
 
33
+ def _local_flows_root(repo_root: Path) -> Path:
34
+ return repo_root / ".codex-autorunner" / "flows"
35
+
36
+
31
37
  def _normalize_component(value: str, label: str) -> str:
32
38
  cleaned = (value or "").strip()
33
39
  if not cleaned:
@@ -68,6 +74,18 @@ def _normalize_archive_rel_path(base: Path, rel_path: str) -> tuple[Path, str]:
68
74
  return candidate, rel_posix
69
75
 
70
76
 
77
+ _LOCAL_ARCHIVE_DIRS = {"archived_tickets", "archived_runs"}
78
+
79
+
80
+ def _normalize_local_archive_rel_path(base: Path, rel_path: str) -> tuple[Path, str]:
81
+ target, rel_posix = _normalize_archive_rel_path(base, rel_path)
82
+ if rel_posix:
83
+ head = rel_posix.split("/", 1)[0]
84
+ if head not in _LOCAL_ARCHIVE_DIRS:
85
+ raise ValueError("invalid archive path")
86
+ return target, rel_posix
87
+
88
+
71
89
  def _resolve_snapshot_root(
72
90
  repo_root: Path,
73
91
  snapshot_id: str,
@@ -108,6 +126,15 @@ def _resolve_snapshot_root(
108
126
  return resolved_root, worktree_id
109
127
 
110
128
 
129
+ def _resolve_local_run_root(repo_root: Path, run_id: str) -> Path:
130
+ run_id = _normalize_component(run_id, "run_id")
131
+ flows_root = _local_flows_root(repo_root)
132
+ run_root = flows_root / run_id
133
+ if not run_root.exists() or not run_root.is_dir():
134
+ raise FileNotFoundError("run archive not found")
135
+ return run_root
136
+
137
+
111
138
  def _safe_mtime(path: Path) -> Optional[float]:
112
139
  try:
113
140
  return path.stat().st_mtime
@@ -194,6 +221,42 @@ def _iter_snapshots(repo_root: Path) -> list[ArchiveSnapshotSummary]:
194
221
  return snapshots
195
222
 
196
223
 
224
+ def _format_mtime(ts: Optional[float]) -> Optional[str]:
225
+ if ts is None:
226
+ return None
227
+ return datetime.fromtimestamp(ts, tz=timezone.utc).isoformat()
228
+
229
+
230
+ def _iter_local_run_archives(repo_root: Path) -> list[LocalRunArchiveSummary]:
231
+ flows_root = _local_flows_root(repo_root)
232
+ if not flows_root.exists() or not flows_root.is_dir():
233
+ return []
234
+ entries: list[tuple[float, LocalRunArchiveSummary]] = []
235
+ for run_dir in sorted(flows_root.iterdir(), key=lambda p: p.name):
236
+ if not run_dir.is_dir():
237
+ continue
238
+ tickets_dir = run_dir / "archived_tickets"
239
+ runs_dir = run_dir / "archived_runs"
240
+ has_tickets = tickets_dir.exists() and tickets_dir.is_dir()
241
+ has_runs = runs_dir.exists() and runs_dir.is_dir()
242
+ if not has_tickets and not has_runs:
243
+ continue
244
+ mtime_candidates = [
245
+ _safe_mtime(tickets_dir) if has_tickets else None,
246
+ _safe_mtime(runs_dir) if has_runs else None,
247
+ ]
248
+ mtime = max([ts for ts in mtime_candidates if ts is not None], default=0.0)
249
+ summary = LocalRunArchiveSummary(
250
+ run_id=run_dir.name,
251
+ archived_at=_format_mtime(mtime) if mtime else None,
252
+ has_tickets=has_tickets,
253
+ has_runs=has_runs,
254
+ )
255
+ entries.append((mtime, summary))
256
+ entries.sort(key=lambda item: (item[0], item[1].run_id), reverse=True)
257
+ return [entry[1] for entry in entries]
258
+
259
+
197
260
  def _list_tree(snapshot_root: Path, rel_path: str) -> ArchiveTreeResponse:
198
261
  target, rel_posix = _normalize_archive_rel_path(snapshot_root, rel_path)
199
262
  if (
@@ -207,6 +270,69 @@ def _list_tree(snapshot_root: Path, rel_path: str) -> ArchiveTreeResponse:
207
270
 
208
271
  root_real = snapshot_root.resolve(strict=False)
209
272
  nodes: list[dict[str, Any]] = []
273
+ for child in sorted(
274
+ target.iterdir(), key=lambda p: p.name
275
+ ): # codeql[py/path-injection] target validated by normalize helper
276
+ try:
277
+ resolved = child.resolve(strict=False)
278
+ resolved.relative_to(root_real)
279
+ except Exception:
280
+ continue
281
+
282
+ if child.is_dir():
283
+ node_type = "folder"
284
+ size_bytes = None
285
+ else:
286
+ node_type = "file"
287
+ try:
288
+ size_bytes = child.stat().st_size
289
+ except OSError:
290
+ size_bytes = None
291
+
292
+ try:
293
+ node_path = resolved.relative_to(root_real).as_posix()
294
+ except ValueError:
295
+ continue
296
+
297
+ nodes.append(
298
+ {
299
+ "path": node_path,
300
+ "name": child.name,
301
+ "type": node_type,
302
+ "size_bytes": size_bytes,
303
+ "mtime": _safe_mtime(child),
304
+ }
305
+ )
306
+
307
+ return ArchiveTreeResponse(path=rel_posix, nodes=nodes)
308
+
309
+
310
+ def _list_local_tree(run_root: Path, rel_path: str) -> ArchiveTreeResponse:
311
+ target, rel_posix = _normalize_local_archive_rel_path(run_root, rel_path)
312
+ if not rel_posix:
313
+ nodes: list[dict[str, Any]] = []
314
+ for name in sorted(_LOCAL_ARCHIVE_DIRS):
315
+ candidate = run_root / name
316
+ if not candidate.exists() or not candidate.is_dir():
317
+ continue
318
+ nodes.append(
319
+ {
320
+ "path": name,
321
+ "name": name,
322
+ "type": "folder",
323
+ "size_bytes": None,
324
+ "mtime": _safe_mtime(candidate),
325
+ }
326
+ )
327
+ return ArchiveTreeResponse(path="", nodes=nodes)
328
+
329
+ if not target.exists():
330
+ raise FileNotFoundError("path not found")
331
+ if not target.is_dir():
332
+ raise ValueError("path is not a directory")
333
+
334
+ root_real = run_root.resolve(strict=False)
335
+ nodes: list[dict[str, Any]] = []
210
336
  for child in sorted(target.iterdir(), key=lambda p: p.name):
211
337
  try:
212
338
  resolved = child.resolve(strict=False)
@@ -251,6 +377,12 @@ def build_archive_routes() -> APIRouter:
251
377
  snapshots = _iter_snapshots(repo_root)
252
378
  return {"snapshots": snapshots}
253
379
 
380
+ @router.get("/local-runs", response_model=LocalRunArchivesResponse)
381
+ def list_local_runs(request: Request):
382
+ repo_root = request.app.state.engine.repo_root
383
+ archives = _iter_local_run_archives(repo_root)
384
+ return {"archives": archives}
385
+
254
386
  @router.get(
255
387
  "/snapshots/{snapshot_id}", response_model=ArchiveSnapshotDetailResponse
256
388
  )
@@ -294,6 +426,22 @@ def build_archive_routes() -> APIRouter:
294
426
  raise HTTPException(status_code=409, detail=str(exc)) from exc
295
427
  return response
296
428
 
429
+ @router.get("/local/tree", response_model=ArchiveTreeResponse)
430
+ def list_local_tree(
431
+ request: Request,
432
+ run_id: str,
433
+ path: str = "",
434
+ ):
435
+ repo_root = request.app.state.engine.repo_root
436
+ try:
437
+ run_root = _resolve_local_run_root(repo_root, run_id)
438
+ response = _list_local_tree(run_root, path)
439
+ except ValueError as exc:
440
+ raise HTTPException(status_code=400, detail=str(exc)) from exc
441
+ except FileNotFoundError as exc:
442
+ raise HTTPException(status_code=404, detail=str(exc)) from exc
443
+ return response
444
+
297
445
  @router.get("/file", response_class=PlainTextResponse)
298
446
  def read_file(
299
447
  request: Request,
@@ -317,6 +465,32 @@ def build_archive_routes() -> APIRouter:
317
465
  if not target.exists() or target.is_dir():
318
466
  raise HTTPException(status_code=404, detail="file not found")
319
467
 
468
+ try:
469
+ content = target.read_text(
470
+ encoding="utf-8", errors="replace"
471
+ ) # codeql[py/path-injection] target validated by normalize helper
472
+ except OSError as exc:
473
+ raise HTTPException(status_code=500, detail=str(exc)) from exc
474
+ return PlainTextResponse(content)
475
+
476
+ @router.get("/local/file", response_class=PlainTextResponse)
477
+ def read_local_file(
478
+ request: Request,
479
+ run_id: str,
480
+ path: str,
481
+ ):
482
+ repo_root = request.app.state.engine.repo_root
483
+ try:
484
+ run_root = _resolve_local_run_root(repo_root, run_id)
485
+ target, rel_posix = _normalize_local_archive_rel_path(run_root, path)
486
+ except ValueError as exc:
487
+ raise HTTPException(status_code=400, detail=str(exc)) from exc
488
+ except FileNotFoundError as exc:
489
+ raise HTTPException(status_code=404, detail=str(exc)) from exc
490
+
491
+ if not rel_posix or not target.exists() or target.is_dir():
492
+ raise HTTPException(status_code=404, detail="file not found")
493
+
320
494
  try:
321
495
  content = target.read_text(encoding="utf-8", errors="replace")
322
496
  except OSError as exc:
@@ -351,6 +525,29 @@ def build_archive_routes() -> APIRouter:
351
525
  filename=target.name,
352
526
  )
353
527
 
528
+ @router.get("/local/download")
529
+ def download_local_file(
530
+ request: Request,
531
+ run_id: str,
532
+ path: str,
533
+ ):
534
+ repo_root = request.app.state.engine.repo_root
535
+ try:
536
+ run_root = _resolve_local_run_root(repo_root, run_id)
537
+ target, rel_posix = _normalize_local_archive_rel_path(run_root, path)
538
+ except ValueError as exc:
539
+ raise HTTPException(status_code=400, detail=str(exc)) from exc
540
+ except FileNotFoundError as exc:
541
+ raise HTTPException(status_code=404, detail=str(exc)) from exc
542
+
543
+ if not rel_posix or not target.exists() or target.is_dir():
544
+ raise HTTPException(status_code=404, detail="file not found")
545
+
546
+ return FileResponse(
547
+ path=target, # codeql[py/path-injection] target validated by normalize helper
548
+ filename=target.name,
549
+ )
550
+
354
551
  return router
355
552
 
356
553
 
@@ -21,6 +21,7 @@ from fastapi.responses import StreamingResponse
21
21
 
22
22
  from ....agents.registry import validate_agent_id
23
23
  from ....core import drafts as draft_utils
24
+ from ....core.context_awareness import CAR_AWARENESS_BLOCK, format_file_role_addendum
24
25
  from ....core.state import now_iso
25
26
  from ....core.utils import atomic_write, find_repo_root
26
27
  from ....integrations.app_server.event_buffer import format_sse
@@ -146,41 +147,20 @@ def _parse_target(repo_root: Path, raw: str) -> _Target:
146
147
  def _build_file_chat_prompt(*, target: _Target, message: str, before: str) -> str:
147
148
  if target.kind == "ticket":
148
149
  file_role_context = (
149
- "This file is a CAR ticket. Ticket flow processes "
150
- "`.codex-autorunner/tickets/TICKET-###*.md` in numeric order.\n"
150
+ f"{format_file_role_addendum('ticket', target.rel_path)}\n"
151
151
  "Edits here change what the ticket flow agent will do; keep YAML "
152
152
  "frontmatter valid."
153
153
  )
154
154
  elif target.kind == "workspace":
155
155
  file_role_context = (
156
- "This file is a CAR workspace doc under `.codex-autorunner/workspace/`."
157
- " These docs act as shared memory across ticket turns."
156
+ f"{format_file_role_addendum('workspace', target.rel_path)}\n"
157
+ "These docs act as shared memory across ticket turns."
158
158
  )
159
159
  else:
160
- file_role_context = (
161
- "This file is a normal repo file (not a CAR ticket/workspace doc)."
162
- )
160
+ file_role_context = format_file_role_addendum("other", target.rel_path)
163
161
 
164
162
  return (
165
- "<injected context>\n"
166
- "You are operating inside a Codex Autorunner (CAR) managed repo.\n\n"
167
- "CAR’s durable control-plane lives under `.codex-autorunner/`:\n"
168
- "- `.codex-autorunner/ABOUT_CAR.md` — short repo-local briefing "
169
- "(ticket/workspace conventions + helper scripts).\n"
170
- "- `.codex-autorunner/tickets/` — ordered ticket queue "
171
- "(`TICKET-###*.md`) used by the ticket flow runner.\n"
172
- "- `.codex-autorunner/workspace/` — shared context docs:\n"
173
- " - `active_context.md` — current “north star” context; kept fresh "
174
- "for ongoing work.\n"
175
- " - `spec.md` — longer spec / acceptance criteria when needed.\n"
176
- " - `decisions.md` — prior decisions / tradeoffs when relevant.\n\n"
177
- "Intent signals: if the user mentions tickets, “dispatch”, “resume”, "
178
- "workspace docs, or `.codex-autorunner/`, they are likely referring "
179
- "to CAR artifacts/workflow rather than generic repo files.\n\n"
180
- "Use the above as orientation. If you need the operational details "
181
- "(exact helper commands, what CAR auto-generates), read "
182
- "`.codex-autorunner/ABOUT_CAR.md`.\n"
183
- "</injected context>\n\n"
163
+ f"{CAR_AWARENESS_BLOCK}\n\n"
184
164
  "<file_role_context>\n"
185
165
  f"{file_role_context}\n"
186
166
  "</file_role_context>\n\n"
@@ -86,6 +86,17 @@ class ArchiveSnapshotDetailResponse(ResponseModel):
86
86
  meta: Optional[Dict[str, Any]] = None
87
87
 
88
88
 
89
+ class LocalRunArchiveSummary(ResponseModel):
90
+ run_id: str
91
+ archived_at: Optional[str] = None
92
+ has_tickets: bool = False
93
+ has_runs: bool = False
94
+
95
+
96
+ class LocalRunArchivesResponse(ResponseModel):
97
+ archives: List[LocalRunArchiveSummary]
98
+
99
+
89
100
  class ArchiveTreeNode(ResponseModel):
90
101
  path: str
91
102
  name: str
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codex-autorunner
3
- Version: 1.2.0
3
+ Version: 1.2.1
4
4
  Summary: Codex autorunner CLI per DESIGN-V1
5
5
  Author: Codex
6
6
  License: MIT License
@@ -27,7 +27,7 @@ codex_autorunner/agents/opencode/run_prompt.py,sha256=b4sZcuRgyHrM2jouEGZGeCw-nO
27
27
  codex_autorunner/agents/opencode/runtime.py,sha256=CTeARdmkCfyp2TB193vG4GeXB1MNPZ4S83OMMqGProE,63958
28
28
  codex_autorunner/agents/opencode/supervisor.py,sha256=KJ-Zz4nE12NsL5QZSMSejPFCiOHKDePVmAnthVwRaFU,18625
29
29
  codex_autorunner/core/__init__.py,sha256=tLqdoJBO1Xvr9umB50rLnn7z-GzMF1VKc-2ZzW7FUTQ,535
30
- codex_autorunner/core/about_car.py,sha256=KoV0jlyiF0V-wtZ1sb2w-GsaNr3HHukt69NL-9iHKWk,11116
30
+ codex_autorunner/core/about_car.py,sha256=iLQOJgkMWPz2naTUKM20grUz-YC3qYbm_cd_WqCC9As,11483
31
31
  codex_autorunner/core/app_server_ids.py,sha256=hn1AOx5RXN2gKtxdgfhFYGaYFAHxOJdgcvp1yqQyRMg,1839
32
32
  codex_autorunner/core/app_server_logging.py,sha256=bXmc03VfpBRX0_WYW6QYJ7XLWpd-hnkJB_EnSr1WFOY,7792
33
33
  codex_autorunner/core/app_server_prompts.py,sha256=Sjx22i7bxb8qFBBvkcFgyvHLEqFbz3IuGKTALRzsfjo,4222
@@ -36,8 +36,8 @@ codex_autorunner/core/app_server_utils.py,sha256=We3SjezC4FFfYcQc8t8g40GWZlJft_1
36
36
  codex_autorunner/core/archive.py,sha256=CyUiGChq9LrbnDOWAi8LgHllcHd79ZxbBIm5O7m_wjk,10415
37
37
  codex_autorunner/core/circuit_breaker.py,sha256=DL8lUrZPluzvNHgCMDUJjWuYytgmVzhL30va8M3TPQ4,6205
38
38
  codex_autorunner/core/codex_runner.py,sha256=iteZnbPnsvfYBopCvvhyWIbnx_eVUJWu6A-gilVGVcw,3353
39
- codex_autorunner/core/config.py,sha256=LxeFJSastIFqbkoLy8RiywR0ms55UAY29a1pNAX0WtI,117531
40
- codex_autorunner/core/context_awareness.py,sha256=5iM9wSFWp_oaZLazAz1qRAgOeX4te07MO9kebd-xdXU,1782
39
+ codex_autorunner/core/config.py,sha256=A3L7po_ojBKIbxaEF5DnLwulw2A_tSbVNhIjjAe3fHo,117533
40
+ codex_autorunner/core/context_awareness.py,sha256=lTV_37vAGtnnMlkCmKyUTmJOAp55mUJMEyHyx_ftU2E,1877
41
41
  codex_autorunner/core/docs.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
42
  codex_autorunner/core/drafts.py,sha256=VeHfBmUpQDFmVZH2RSbZHCi7lIiMVrCFRf0iENlreEY,4202
43
43
  codex_autorunner/core/exceptions.py,sha256=CJAOtYagbVSieCxJiP3ndp-sBvjcQVYBz6LLKzKKaWA,1600
@@ -53,7 +53,7 @@ codex_autorunner/core/optional_dependencies.py,sha256=sBuSnQrRhV6_JA2tVLlVnDBsED
53
53
  codex_autorunner/core/patch_utils.py,sha256=H5IPB5X4EJmXw7dNV3hj6m-vV2yXNY4PMuvq12msV7o,7635
54
54
  codex_autorunner/core/path_utils.py,sha256=2TwtUY8YvIbc4fyqVcZalzBVTmk5uDMpeUg7ZDAt0h4,3492
55
55
  codex_autorunner/core/pma_audit.py,sha256=QtDbR6yD4kdk8JV67fjeidNjOga8S2rLUsUNX7BSxJE,8022
56
- codex_autorunner/core/pma_context.py,sha256=Xm63zxRcQ0DybQaJOXhwde1ADPGq8iQMeFIUhEhtvIE,16559
56
+ codex_autorunner/core/pma_context.py,sha256=QH3cRL4OdJXIbH8daOyy8ppVIhJzWpYnr2B-BSrWaSA,24631
57
57
  codex_autorunner/core/pma_dispatch_interceptor.py,sha256=WZZfNJKAciqLdpJm02tE1t3WndU7nLO4z9xQcOb0wJk,9203
58
58
  codex_autorunner/core/pma_lifecycle.py,sha256=p60VgkpXxY0evLNPJj4-OhWIG6BXP4IepLyins4lhNE,16997
59
59
  codex_autorunner/core/pma_queue.py,sha256=R7AvfqWWxpER3lkhuP1d1eLD_LK-94oJyVmF7TKP4CM,12464
@@ -125,10 +125,10 @@ codex_autorunner/integrations/app_server/supervisor.py,sha256=7VAXeyufWRkqHrcaV4
125
125
  codex_autorunner/integrations/github/__init__.py,sha256=mLMQATB-B_LbgebPRCdWqUDS-cMxXfuALGh_RsWbWBk,224
126
126
  codex_autorunner/integrations/github/service.py,sha256=484jkhg_lnDap0jMatspuMNn04cg7uVqAG2GctF17Co,39015
127
127
  codex_autorunner/integrations/telegram/__init__.py,sha256=oAEE1Yb-7Ybgb79NLWqNErkSXOGBJDgcvlI7gfHlpDA,36
128
- codex_autorunner/integrations/telegram/adapter.py,sha256=YPFLrFxtYu_nfOGEG-dzWcjeWioBsCtG7bzxy1R66l0,56820
128
+ codex_autorunner/integrations/telegram/adapter.py,sha256=mQmkKwiEoKLKjfAXw_a4gLmnifS_MS6XHP_KeWOAB4c,56821
129
129
  codex_autorunner/integrations/telegram/api_schemas.py,sha256=IXwB17Y4wL0lborU8HHssgNgOtHUJYLoMAcyb3Jv7_8,3402
130
130
  codex_autorunner/integrations/telegram/commands_registry.py,sha256=C5T6KeTUq4DmhmSe9FwNRg_kNJWKcYB4hxthVu7MbAQ,3153
131
- codex_autorunner/integrations/telegram/config.py,sha256=9xp66k479EedIGssi24UIm8EvCAtBuGL_ea4kkmdGEA,32312
131
+ codex_autorunner/integrations/telegram/config.py,sha256=xxTQY4foUyWMYdEPZkdb7DV2E-ucCqXUhQGH-8RUocA,32313
132
132
  codex_autorunner/integrations/telegram/constants.py,sha256=16-CnkenzOrXAslfFXKYAMBmBUVPltAHfSuBWqq0Eag,6741
133
133
  codex_autorunner/integrations/telegram/dispatch.py,sha256=dgh95aYuvveqS7TGvbYHKbtT2RYFx1qGq7mGYyRY2xI,6916
134
134
  codex_autorunner/integrations/telegram/doctor.py,sha256=uZNxQsnRGaQnu6GpoHVve5ELkSDO6FPCN4_byj6XbQo,9667
@@ -152,7 +152,7 @@ codex_autorunner/integrations/telegram/handlers/approvals.py,sha256=G8-FwRSyyBs9
152
152
  codex_autorunner/integrations/telegram/handlers/callbacks.py,sha256=wyF8Kmg69KHpKdlPj1DOhp3EEQ3rZ0sjxHnomApSAKw,3754
153
153
  codex_autorunner/integrations/telegram/handlers/commands_runtime.py,sha256=b935T6ML8lG8VUjAZQQ5M1nDR0rDU-1rq-u9HWez7oY,108920
154
154
  codex_autorunner/integrations/telegram/handlers/commands_spec.py,sha256=B9nzbALNmcxCzgz6MSHJgYy7lJgt4xgT9E41XrxVlqk,5629
155
- codex_autorunner/integrations/telegram/handlers/messages.py,sha256=2MOy2nxyStU3l4-fJ9_YMfjsyVovju9o9Fn64PwzK9Y,32665
155
+ codex_autorunner/integrations/telegram/handlers/messages.py,sha256=lC6VAoY_NR8uJbO5D_tKykr2vWTy0Xu2JnJ9zyuy-Vc,32904
156
156
  codex_autorunner/integrations/telegram/handlers/questions.py,sha256=GoOZzyYPqOt9jW4T27EzjNUOQrMgf3i3F6fJ6tWILzI,15570
157
157
  codex_autorunner/integrations/telegram/handlers/selections.py,sha256=JSg_ihLMkK1L3aH8XPEFbO5EaYY5ZWddwPztkNkA-Wc,25055
158
158
  codex_autorunner/integrations/telegram/handlers/utils.py,sha256=T2y-2p1SNduypiNz9uq4zqRIFq47z9Lop6_s3nhUzN8,5317
@@ -188,14 +188,14 @@ codex_autorunner/routes/workspace.py,sha256=j_-z5kSU5pMC2obOyqJj4HYW35pquVwy7swB
188
188
  codex_autorunner/static/agentControls.js,sha256=U8c8s9ueKOBD8rgLJS5gseebKnXnxYfMnQqttY2MS8U,13745
189
189
  codex_autorunner/static/agentEvents.js,sha256=HAQHeKJnOqj6IkcBEM1ye5p6rcIjK9c9LZfBWKowonw,8188
190
190
  codex_autorunner/static/app.js,sha256=rxtxK_Tw4l6rXxRycE7a-rHoZaOTne901CQbmLQ0ZyU,7658
191
- codex_autorunner/static/archive.js,sha256=OsdQ_OwOiSsA1mDPtPO_fEUuVZ0XsDGfE20Ddnd7RII,31544
192
- codex_autorunner/static/archiveApi.js,sha256=da5envEoMUK0WF_iQScWjUhEeQPaCilsGGbWNyK_MnA,1622
191
+ codex_autorunner/static/archive.js,sha256=a8R8WYBLkju_Mhzs8waX3Uf_tMahejyGbK4TvNhBCSk,40176
192
+ codex_autorunner/static/archiveApi.js,sha256=cvooxgTKmV_gnYl9YNKOYwYOh6KaV8QwCIjNTKcUj3k,2478
193
193
  codex_autorunner/static/autoRefresh.js,sha256=8nsJmnIpD1Ga02kdUIFNAA3Z3-lw-7kLJMjR4Ve0aE8,6694
194
194
  codex_autorunner/static/bootstrap.js,sha256=ZXzMfDMjiC5ReOrDbv9lqSBaTZQlM7eqEAJ4IKPhm5s,4833
195
195
  codex_autorunner/static/bus.js,sha256=NXuNHd_43Irr-5Ood1LQ15rSwCTm5J_Pv9ybnkeGQM0,630
196
196
  codex_autorunner/static/cache.js,sha256=idp3ISlRKjSK_eSRUmL_rWGI2qx7g-BJ1_48Mz6IWSw,1035
197
197
  codex_autorunner/static/chatUploads.js,sha256=oFKWPAHnESvk0aqFTH40A3-90fai78GGS9KXSr1RZsk,5174
198
- codex_autorunner/static/constants.js,sha256=TuLK0-_WKJVE5uJUeTl_CVtD5laEtTjtTnu0Uv2eIFw,1932
198
+ codex_autorunner/static/constants.js,sha256=vmlDFXF6JYRrX3XJ0rJ_Ft1w-AMa7RdhHq8pTGhRR3Q,2036
199
199
  codex_autorunner/static/dashboard.js,sha256=15gI7rxhtG6Ngnw_N9iNHSkALkaaGRIYCYoqEJxwOe4,30749
200
200
  codex_autorunner/static/diffRenderer.js,sha256=AVeJ6yt8UBk6yQJWV6VCIsH9TIY5CYTCjNFD8uOWQ9U,1307
201
201
  codex_autorunner/static/docChatCore.js,sha256=LSn_Z7MHh7FtiRexXtxfXGdjN9mjfkdQODxgcAc90h0,22724
@@ -213,17 +213,17 @@ codex_autorunner/static/liveUpdates.js,sha256=SiVWPQRp-mqmmhRqOQWPFtMBLUA89J1KYv
213
213
  codex_autorunner/static/loader.js,sha256=2Xyg_D43sSsH3fmm93-utyPJJSQ7KpvebbhNrM79ljo,1065
214
214
  codex_autorunner/static/messages.js,sha256=xLjw2LJMy6ng1cgEsCcZZ7SN4PXeNSFEVkJycQVhe8Y,35287
215
215
  codex_autorunner/static/mobileCompact.js,sha256=cDXLGeFLj5_knH-9qOXfbR5IXjCttyQ3-jclL4k1ouo,9473
216
- codex_autorunner/static/notifications.js,sha256=WauZLW1M4oPX9y9mtMklioVpzlPu7cu06aWgIBgEz2E,8992
216
+ codex_autorunner/static/notifications.js,sha256=R8h9DhW5Tzr6X4A4fYFacI6Y--zvB7eJgJBRFRWVmW4,10430
217
217
  codex_autorunner/static/pma.js,sha256=eA_jyCXjaLetVQ02-jacfLN813xYSM4yaGIesCJ9ssc,42857
218
218
  codex_autorunner/static/preserve.js,sha256=cOB-kcPQPHYDZqwkJFi69n6LhT51BHNWGL6zLRPsJyM,437
219
219
  codex_autorunner/static/settings.js,sha256=ouKultNn5PUXt4tFr9CkkQdTMDwC_RtSTIbyuz-12Vs,9989
220
220
  codex_autorunner/static/smartRefresh.js,sha256=0BovWNSXgeqkcawiF0JfZf7Zu81Nqr2Ni4qCj0EeJ6I,1713
221
221
  codex_autorunner/static/streamUtils.js,sha256=EXbXeDUKUry953W3noyWo-2dpZxVVkfgbwiFT3eAXLQ,2128
222
- codex_autorunner/static/styles.css,sha256=srBoQ3KL6UW2zl80ThpgFE0c9a8hDciRjjxMYfrcuGc,253919
222
+ codex_autorunner/static/styles.css,sha256=jlZFD_nch9AJvYjNSw-_5havgbN9aGNrjeGYh2vC49w,254138
223
223
  codex_autorunner/static/tabs.js,sha256=SgebpOJIxzkD307VQ1NmXBpLY40b1g8RvNIcf2fmVlI,8429
224
224
  codex_autorunner/static/templateReposSettings.js,sha256=w-YmI-zbSpiVE_MHew3Ly2kJRF81_QbV-GMl8MAfq9E,7121
225
225
  codex_autorunner/static/terminal.js,sha256=EEnwfA8rcOt1vOQngXdOTpymdqsYoBA-XPmFoksaHcs,1621
226
- codex_autorunner/static/terminalManager.js,sha256=_KqMvFqCq3t5St_Bxl7pC8w9KAvOth9InT56hUSnZxc,139493
226
+ codex_autorunner/static/terminalManager.js,sha256=muOWh9CU66YN74sVSogINLStt25EgBM4p7J7adm1XtE,139931
227
227
  codex_autorunner/static/ticketChatActions.js,sha256=4BsA_eUb3fV0qqK7GO1s7BvZiVIH1F7ggm773x5BS9E,18026
228
228
  codex_autorunner/static/ticketChatEvents.js,sha256=9Y1CA4t--bxqXRHrsE4O4Dx5Td9KAFAAZwLXXj_y1yM,536
229
229
  codex_autorunner/static/ticketChatStorage.js,sha256=lEg2zKJfEA34ZS0azwCmGPW8CPpX3wqCmyNcCafP9Yw,621
@@ -275,7 +275,7 @@ codex_autorunner/surfaces/web/middleware.py,sha256=4mh4EikDLWWByLx3O5nQvMcqHOUFp
275
275
  codex_autorunner/surfaces/web/pty_session.py,sha256=K1_hJFYy-xh90o1hDezmsC3euP7ifsgHMzAg1E9HZA8,12791
276
276
  codex_autorunner/surfaces/web/review.py,sha256=70KXs1-b15f1CXuRfWHgHpriHzcyPbpMkEFY25AOzNo,166
277
277
  codex_autorunner/surfaces/web/runner_manager.py,sha256=V1oA0e8qFpVz1wNGr-67lEMoe4jTo5x7DULgOrp2bx8,665
278
- codex_autorunner/surfaces/web/schemas.py,sha256=Py7hljRZ_e8epRFbfc7-GNie9sYV2KgkYAxJP126v4k,10711
278
+ codex_autorunner/surfaces/web/schemas.py,sha256=nNMkBt4mSfH2U7ea8NJVIiazh3qnN-SfkdVKyvbH7EA,10961
279
279
  codex_autorunner/surfaces/web/static_assets.py,sha256=Mo0FJ0ALM-NlUpkWJIMKC2Vq5JX6ZeOe3w_h_VK5uys,15178
280
280
  codex_autorunner/surfaces/web/static_refresh.py,sha256=Rv40lPd3eRDqcwnF6CXlwRaV5kNPkcXund7zjY7YqGM,3145
281
281
  codex_autorunner/surfaces/web/terminal_sessions.py,sha256=uol4tWorQ-EcJHLWNS6MQb8otpGFR1CaXuzutGMOgO0,2651
@@ -283,9 +283,9 @@ codex_autorunner/surfaces/web/routes/__init__.py,sha256=laWu7u2pF5Xelmsaap-WVMCY
283
283
  codex_autorunner/surfaces/web/routes/agents.py,sha256=w3yC3KxNMy16015YFS9FNRLLiIq9CvFM7culln7ByqA,5541
284
284
  codex_autorunner/surfaces/web/routes/analytics.py,sha256=1P4TP_icwWYY2ddLYHaCTTxgkc_1QrRch12nakOtCrY,10140
285
285
  codex_autorunner/surfaces/web/routes/app_server.py,sha256=vPy0nsw7wqQpK_4Iquffa6Aox4ksuyBx1hHfvrek040,5351
286
- codex_autorunner/surfaces/web/routes/archive.py,sha256=IjYtIi0P_WucFxppoqRLnSuFaFcclSKx9kiDnAbJ5vU,12514
286
+ codex_autorunner/surfaces/web/routes/archive.py,sha256=hH5U7wnBAeUFyE99dKbmAKTbYBd2zwBjzW-tokJQzJw,19702
287
287
  codex_autorunner/surfaces/web/routes/base.py,sha256=JV8kpXuaPkoJh9DBq--k9CdEM2VZwqfBDTEUE8EqGRg,26662
288
- codex_autorunner/surfaces/web/routes/file_chat.py,sha256=IVvG5TmeTruY4Geo6qMZV1P3U5xIiXCTvQ-tFs565XQ,41880
288
+ codex_autorunner/surfaces/web/routes/file_chat.py,sha256=IN_fy7AoWKvfnJFwSz8C64u-JG-Hv3bueG9V6p7un6s,40630
289
289
  codex_autorunner/surfaces/web/routes/filebox.py,sha256=HdRRAjh80o4IfDkUbsuPUXflQ96fcJ6KBDQHmq42mcA,8084
290
290
  codex_autorunner/surfaces/web/routes/flows.py,sha256=C9SpQwmnVb5t3xfxluNTrhG1fHlUkRTrV-evzxptUB4,50327
291
291
  codex_autorunner/surfaces/web/routes/messages.py,sha256=XEIH24jfHUN3e00hopDmiXnADLo0h6Shw9Ie-nHAdPs,18070
@@ -331,9 +331,9 @@ codex_autorunner/web/static_refresh.py,sha256=4QY5FK5T8ymsBIuSeuLWcx9yXL8LyO4Usc
331
331
  codex_autorunner/web/terminal_sessions.py,sha256=8Pa4gKd-ZUjwqEDUInAgEPRP14CouBEZqgvXRKzNjEg,119
332
332
  codex_autorunner/workspace/__init__.py,sha256=yTql6_7BVZG0tirPMhbmMEVkk_j7Q8Wvb89eIZ0K7o8,977
333
333
  codex_autorunner/workspace/paths.py,sha256=mScZQpKPyFYvxEmyr_51PfWP_7aTAWkRT4AZWqGnME4,10785
334
- codex_autorunner-1.2.0.dist-info/licenses/LICENSE,sha256=gfYghezUeimFKy0hTmkOiAAwBY_QdRSXDTypbMtZU0k,1068
335
- codex_autorunner-1.2.0.dist-info/METADATA,sha256=1xmI7p6haabEJXOlVpgH2_gTx3W2gjNBON_RK2CW5Bo,8914
336
- codex_autorunner-1.2.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
337
- codex_autorunner-1.2.0.dist-info/entry_points.txt,sha256=iPTzENG1MGBhxWF4x8W7VWk3iq4XurmGXMnIch7AVTs,93
338
- codex_autorunner-1.2.0.dist-info/top_level.txt,sha256=fc2h9rEENr-ZdyLemPJbMcWmsWlz4JuyD1UOkPLLVSQ,17
339
- codex_autorunner-1.2.0.dist-info/RECORD,,
334
+ codex_autorunner-1.2.1.dist-info/licenses/LICENSE,sha256=gfYghezUeimFKy0hTmkOiAAwBY_QdRSXDTypbMtZU0k,1068
335
+ codex_autorunner-1.2.1.dist-info/METADATA,sha256=5vxuxvkrCjyAPljglJZNqKAi1-Xph2ARbDChMturQeg,8914
336
+ codex_autorunner-1.2.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
337
+ codex_autorunner-1.2.1.dist-info/entry_points.txt,sha256=iPTzENG1MGBhxWF4x8W7VWk3iq4XurmGXMnIch7AVTs,93
338
+ codex_autorunner-1.2.1.dist-info/top_level.txt,sha256=fc2h9rEENr-ZdyLemPJbMcWmsWlz4JuyD1UOkPLLVSQ,17
339
+ codex_autorunner-1.2.1.dist-info/RECORD,,