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.
- codex_autorunner/core/about_car.py +12 -12
- codex_autorunner/core/config.py +2 -2
- codex_autorunner/core/context_awareness.py +1 -0
- codex_autorunner/core/pma_context.py +188 -1
- codex_autorunner/integrations/telegram/adapter.py +1 -1
- codex_autorunner/integrations/telegram/config.py +1 -1
- codex_autorunner/integrations/telegram/handlers/messages.py +8 -2
- codex_autorunner/static/archive.js +274 -81
- codex_autorunner/static/archiveApi.js +21 -0
- codex_autorunner/static/constants.js +1 -1
- codex_autorunner/static/notifications.js +33 -0
- codex_autorunner/static/styles.css +16 -0
- codex_autorunner/static/terminalManager.js +22 -3
- codex_autorunner/surfaces/web/routes/archive.py +197 -0
- codex_autorunner/surfaces/web/routes/file_chat.py +6 -26
- codex_autorunner/surfaces/web/schemas.py +11 -0
- {codex_autorunner-1.2.0.dist-info → codex_autorunner-1.2.1.dist-info}/METADATA +1 -1
- {codex_autorunner-1.2.0.dist-info → codex_autorunner-1.2.1.dist-info}/RECORD +22 -22
- {codex_autorunner-1.2.0.dist-info → codex_autorunner-1.2.1.dist-info}/WHEEL +0 -0
- {codex_autorunner-1.2.0.dist-info → codex_autorunner-1.2.1.dist-info}/entry_points.txt +0 -0
- {codex_autorunner-1.2.0.dist-info → codex_autorunner-1.2.1.dist-info}/licenses/LICENSE +0 -0
- {codex_autorunner-1.2.0.dist-info → codex_autorunner-1.2.1.dist-info}/top_level.txt +0 -0
|
@@ -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
|
-
|
|
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
|
-
"
|
|
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
|
-
"
|
|
157
|
-
"
|
|
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
|
-
"
|
|
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
|
|
@@ -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=
|
|
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=
|
|
40
|
-
codex_autorunner/core/context_awareness.py,sha256=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
192
|
-
codex_autorunner/static/archiveApi.js,sha256=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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.
|
|
335
|
-
codex_autorunner-1.2.
|
|
336
|
-
codex_autorunner-1.2.
|
|
337
|
-
codex_autorunner-1.2.
|
|
338
|
-
codex_autorunner-1.2.
|
|
339
|
-
codex_autorunner-1.2.
|
|
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,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|