Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
e2a0eda
feat(storage): archived cleanup with quarantine default (phase 2)
Wibias Jul 27, 2026
888e434
fix(storage): address CodeRabbit review on cleanup APIs and i18n
Wibias Jul 27, 2026
1f634e7
fix(storage): bind cleanup to preview digest and make it atomic
Wibias Jul 27, 2026
1f794c6
fix(storage): resolve remaining CodeRabbit cleanup review notes
Wibias Jul 27, 2026
6ae3bd5
fix(storage): write cleanup manifest before DB commit
Wibias Jul 27, 2026
87ffd78
fix(gui): sync cleanup busyRef in an effect
Wibias Jul 27, 2026
8ec1ca1
fix(storage): address CodeRabbit TOCTOU and recovery messaging
Wibias Jul 27, 2026
da163b1
fix(gui): reset permanent mode on dismiss and localize presets
Wibias Jul 27, 2026
8f0ed9a
fix(storage): reconcile logs/goals/memories on archived cleanup
Wibias Jul 27, 2026
b9af3fd
fix(storage): make multi-DB cleanup recoverable under state lock
Wibias Jul 27, 2026
7209c27
fix(storage): persist full satellite backup before any delete commit
Wibias Jul 27, 2026
f545c24
fix(storage): hold satellite write locks through snapshot and delete
Wibias Jul 27, 2026
9a9653e
fix(storage): make satellite lock acquisition and consolidate restore…
Wibias Jul 27, 2026
df23423
test(storage): close read-only SQLite handles in busy-satellite regre…
Wibias Jul 27, 2026
8fe960c
fix(storage): address Codex review on cleanup safety and recovery
Wibias Jul 27, 2026
2caecb9
fix(storage): address CodeRabbit review on chunking and errors
Wibias Jul 27, 2026
3b0c85d
fix(storage): allowlist cleanup test hooks on management API
Wibias Jul 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs-site/src/content/docs/guides/web-dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ bun run dev:gui
| **Models** | Toggle native GPT and routed models, set provider allowlists and context caps, choose v1/base/v2, and configure the v2 thread limit. Configured providers stay visible as zero-model groups when discovery is off or returns no rows. |
| **Logs** | Auto-refresh recent requests with tokens, requested effort and (when available) effective outbound effort, resolved model, provider, status, request id, duration, and error details. The detail view includes the exact reasoning wire field when the adapter emits one. Filter by opaque conversation/session id (when the client sends one) to total tokens and estimated list-price cost for the currently loaded Logs ring. |
| **Usage / Debug** | Inspect token-usage coverage and trends, or enable opt-in provider transport and usage-extraction diagnostics. |
| **Storage** | Read-only CODEX_HOME disk breakdown (sessions, archives, DBs, attachments). Optional archived cleanup: preview the oldest N%, then quarantine to `CODEX_HOME/.trash` (default) or permanently delete behind an explicit checkbox. Active sessions stay read-only. Cleanup is refused while Codex holds the newest/active `state_*.sqlite` locked. Quarantined files are **not** restorable from the dashboard — recover manually from `.trash/<epoch>/` using `manifest.json` if needed. |
| **Stop** | Gracefully stop the proxy and installed background service, restore native Codex, and exit (`POST /api/stop`). |

### Linking to a section
Expand Down
1 change: 1 addition & 0 deletions docs-site/src/content/docs/ja/guides/web-dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ bun run dev:gui
| **モデル** | ネイティブ GPT とルーティングモデルをオン/オフし、プロバイダー許可リストとコンテキスト上限、v1/base/v2、v2 スレッド数を設定します。 |
| **ログ** | トークン、要求された強度と(利用可能な場合は)実際に送信された強度、実際のモデル、プロバイダー、状態、リクエスト ID、所要時間、エラー詳細を含む最近のリクエストを自動更新します。アダプターが reasoning パラメーターを送信した場合、詳細表示に正確な wire field も表示されます。 |
| **使用量 / デバッグ** | トークン使用量の測定範囲と推移を見るか、オプションのプロバイダートランスポート/使用量抽出診断をオンにします。 |
| **ストレージ** | CODEX_HOME のディスク内訳(セッション、アーカイブ、DB、添付)を読み取り専用で表示。任意のアーカイブクリーンアップ: 最古 N% をプレビューし、既定では `CODEX_HOME/.trash` へ隔離、または明示チェックで完全削除。アクティブセッションは読み取り専用。最新/アクティブな `state_*.sqlite` がロック中は拒否。隔離分はダッシュボードから復元不可 — 必要なら `.trash/<epoch>/` と `manifest.json` から手動復旧。 |
| **停止** | プロキシとインストールされたバックグラウンドサービスを正常終了しネイティブ Codex を復元した後終了します(`POST /api/stop`)。 |

### セクションへのリンク
Expand Down
1 change: 1 addition & 0 deletions docs-site/src/content/docs/ko/guides/web-dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ bun run dev:gui
| **Models** | 네이티브 GPT와 라우팅 모델을 켜고 끄고, 프로바이더 allowlist와 컨텍스트 상한, v1/base/v2, v2 thread 수를 설정합니다. |
| **Logs** | 토큰, 요청한 강도와 (사용 가능한 경우) 실제 전송 강도, 실제 모델, 프로바이더, 상태, 요청 id, 소요 시간, 오류 상세가 포함된 최근 요청을 자동 갱신합니다. 어댑터가 reasoning 매개변수를 전송한 경우 상세 보기에 정확한 wire field도 표시됩니다. 클라이언트가 보낸 불투명 대화/세션 id로 필터하면 현재 로드된 Logs 링의 토큰·추정 정가 합계를 볼 수 있습니다. |
| **Usage / Debug** | 토큰 사용량의 측정 범위와 추이를 보거나, 선택적 프로바이더 전송/사용량 추출 진단을 켭니다. |
| **Storage** | CODEX_HOME 디스크 사용량(세션, 보관, DB, 첨부)을 읽기 전용으로 표시합니다. 선택적 보관 정리: 가장 오래된 N%를 미리본 뒤 기본으로 `CODEX_HOME/.trash`에 격리하거나, 명시 체크 후 영구 삭제합니다. 활성 세션은 읽기 전용입니다. Codex가 최신/활성 `state_*.sqlite`를 잠그면 거절합니다. 격리 파일은 대시보드에서 복원할 수 없습니다 — 필요하면 `.trash/<epoch>/`와 `manifest.json`으로 수동 복구하세요. |
| **Stop** | 프록시와 설치된 백그라운드 서비스를 정상 종료하고 네이티브 Codex를 복원한 뒤 끝냅니다(`POST /api/stop`). |

### 섹션으로 바로 가기
Expand Down
1 change: 1 addition & 0 deletions docs-site/src/content/docs/ru/guides/web-dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ bun run dev:gui
| **Models** | Включение и отключение нативных GPT и маршрутизируемых моделей, настройка списков разрешённых провайдеров и лимитов контекста, выбор v1/base/v2 и настройка лимита потоков v2. |
| **Logs** | Автообновляемый список недавних запросов: токены, запрошенный и, когда доступен, фактически отправленный уровень рассуждений, фактическая модель, провайдер, статус, id запроса, длительность и подробности ошибок. Если адаптер отправляет параметр рассуждений, в подробностях также отображается точное wire-поле. Можно фильтровать по непрозрачному id диалога/сессии (если клиент его передаёт) и суммировать токены и оценочную стоимость по прайс-листу в пределах загруженного кольца Logs. |
| **Usage / Debug** | Просмотр покрытия и трендов расхода токенов либо включение опциональной диагностики транспорта провайдеров и извлечения данных об использовании. |
| **Storage** | Только чтение разбивки диска CODEX_HOME (сессии, архивы, БД, вложения). Опциональная очистка архива: предпросмотр самых старых N%, затем карантин в `CODEX_HOME/.trash` (по умолчанию) или безвозвратное удаление по явному флажку. Активные сессии только для чтения. Очистка отклоняется, пока Codex держит блокировку новейшего/активного `state_*.sqlite`. Из карантина **нельзя** восстановить через панель — вручную из `.trash/<epoch>/` и `manifest.json`. |
| **Stop** | Корректная остановка прокси и установленного фонового сервиса, восстановление нативного Codex и выход (`POST /api/stop`). |

### Ссылки на разделы
Expand Down
1 change: 1 addition & 0 deletions docs-site/src/content/docs/zh-cn/guides/web-dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ bun run dev:gui
| **Models** | 开关原生 GPT 与路由模型,配置 provider allowlist、上下文上限、v1/base/v2 以及 v2 thread 数量。 |
| **Logs** | 自动刷新近期请求,显示 token、请求强度以及(可用时)实际发送强度、实际模型、provider、状态、request id、耗时和错误详情。适配器发送 reasoning 参数时,详情中还会显示准确的 wire field。可按不透明会话/对话 ID(客户端提供时)筛选,并对当前已加载的 Logs 环形缓冲合计 token 与估算标价成本。 |
| **Usage / Debug** | 查看 token usage 覆盖率与趋势,或启用可选的 provider transport 和 usage 提取诊断。 |
| **Storage** | 只读查看 CODEX_HOME 磁盘占用(会话、归档、数据库、附件)。可选归档清理:预览最旧 N%,默认隔离到 `CODEX_HOME/.trash`,或勾选后永久删除。活动会话保持只读。Codex 锁定最新/活动的 `state_*.sqlite` 时拒绝清理。隔离文件**不能**从仪表盘恢复——如需恢复,请根据 `manifest.json` 将文件从 `.trash/<epoch>/` 手动移回原位置。 |
| **Stop** | 优雅地停止代理和已安装的后台服务,恢复原生 Codex 并退出(`POST /api/stop`)。 |

### 链接到某个部分
Expand Down
30 changes: 29 additions & 1 deletion gui/src/i18n/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -864,7 +864,7 @@ export const de: Record<TKey, string> = {

"nav.storage": "Speicher",
"storage.title": "Speicher",
"storage.subtitle": "Schreibgeschützte Übersicht, wohin der CODEX_HOME-Speicher geht. Nichts auf dieser Seite löscht etwas.",
"storage.subtitle": "Diagnose zur CODEX_HOME-Festplattennutzung. Die Archivbereinigung unten kann älteste archivierte Sitzungen in Quarantäne legen oder dauerhaft löschen — aktive Sitzungen bleiben schreibgeschützt.",
"storage.loading": "Speicher wird gescannt…",
"storage.empty": "CODEX_HOME ist leer oder fehlt — nichts zu berichten.",
"storage.error": "Speicher-Scan fehlgeschlagen. Prüfe, ob CODEX_HOME auf ein gültiges Verzeichnis zeigt.",
Expand All @@ -888,6 +888,34 @@ export const de: Record<TKey, string> = {
"storage.bucket.attachments": "Anhänge",
"storage.bucket.deletion_manifests": "Lösch-Manifeste",
"storage.bucket.other": "Sonstiges",
"storage.cleanup.title": "Archivbereinigung",
"storage.cleanup.help": "Entfernt die ältesten archivierten Sitzungen nach Prozentsatz. Aktive Sitzungen werden nie angefasst. Standard ist Quarantäne — Dateien wandern nach CODEX_HOME/.trash.",
"storage.cleanup.slider": "Ältester Archivanteil",
"storage.cleanup.percent": "Älteste {percent}%",
"storage.cleanup.preset": "{percent}",
"storage.cleanup.preview": "Vorschau",
"storage.cleanup.confirmTitle": "Archivbereinigung bestätigen",
"storage.cleanup.confirmBody": "Es werden {count} archivierte Datei(en) (~{size}) verarbeitet, die ältesten {percent}%.",
"storage.cleanup.moreFiles": "…und {n} weitere",
"storage.cleanup.permanent": "Dauerhaft löschen (ohne Quarantäne)",
"storage.cleanup.permanentWarn": "Dauerhaftes Löschen kann nicht rückgängig gemacht werden.",
"storage.cleanup.quarantineNote": "Dateien wandern nach .trash unter CODEX_HOME. In dieser Version gibt es keine App-Wiederherstellung — behalte den Ordner oder verschiebe Dateien manuell anhand von manifest.json zurück.",
"storage.cleanup.cancel": "Abbrechen",
"storage.cleanup.confirmQuarantine": "In Quarantäne",
"storage.cleanup.confirmPermanent": "Dauerhaft löschen",
"storage.cleanup.doneQuarantine": "{count} Datei(en) in Quarantäne ({size}).",
"storage.cleanup.donePermanent": "{count} Datei(en) dauerhaft gelöscht ({size}).",
"storage.cleanup.previewFailed": "Vorschau fehlgeschlagen.",
"storage.cleanup.cleanupFailed": "Bereinigung fehlgeschlagen.",
"storage.cleanup.err.codex_busy": "Codex verwendet state.sqlite — beende Codex und versuche es erneut.",
"storage.cleanup.err.stale_preview": "Archivdateien haben sich seit der Vorschau geändert — führe Vorschau erneut aus.",
"storage.cleanup.err.referenced_history": "Ausgewählte Archive werden noch von Fork- oder paginierter Historie referenziert.",
"storage.cleanup.err.invalid_digest": "Vorschaudigest fehlt oder ist ungültig.",
"storage.cleanup.err.invalid_mode": "Modus muss quarantine oder permanent sein.",
"storage.cleanup.err.fs_failed": "Dateisystem-Bereinigung fehlgeschlagen. Einige Änderungen können bereits angewendet sein — prüfen Sie CODEX_HOME/.trash und den angezeigten Wiederherstellungspfad.",
"storage.cleanup.err.fs_failed_trash": "Dateisystem-Bereinigung fehlgeschlagen. Einige Änderungen können bereits angewendet sein — prüfen Sie {trashDir} und manifest.json auf wiederherstellbare Dateien.",
"storage.cleanup.err.db_reconcile_failed": "Codex-Statusdatenbank konnte nicht aktualisiert werden.",
"storage.cleanup.err.cleanup_failed": "Bereinigung fehlgeschlagen.",
"modal.back": "Zurück",
"modal.badge.oauth": "OAuth",
"modal.customProvider": "Benutzerdefinierter Anbieter",
Expand Down
30 changes: 29 additions & 1 deletion gui/src/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@ export const en = {

"nav.storage": "Storage",
"storage.title": "Storage",
"storage.subtitle": "Read-only view of where your CODEX_HOME disk goes. Nothing on this page deletes anything.",
"storage.subtitle": "Diagnostics for CODEX_HOME disk use. Archived cleanup below can quarantine or permanently delete oldest archived sessions — active sessions stay read-only.",
"storage.loading": "Scanning storage…",
"storage.empty": "CODEX_HOME is empty or missing — nothing to report.",
"storage.error": "Storage scan failed. Check that CODEX_HOME points at a valid directory.",
Expand All @@ -637,6 +637,34 @@ export const en = {
"storage.bucket.attachments": "Attachments",
"storage.bucket.deletion_manifests": "Deletion manifests",
"storage.bucket.other": "Other",
"storage.cleanup.title": "Archived cleanup",
"storage.cleanup.help": "Remove the oldest archived sessions by percentage. Active sessions are never touched. Quarantine is the default — files move to CODEX_HOME/.trash.",
"storage.cleanup.slider": "Oldest archived percent",
"storage.cleanup.percent": "Oldest {percent}%",
"storage.cleanup.preset": "{percent}",
"storage.cleanup.preview": "Preview",
"storage.cleanup.confirmTitle": "Confirm archived cleanup",
"storage.cleanup.confirmBody": "This will process {count} archived file(s) (~{size}), the oldest {percent}%.",
"storage.cleanup.moreFiles": "…and {n} more",
"storage.cleanup.permanent": "Delete permanently (skip quarantine)",
"storage.cleanup.permanentWarn": "Permanent delete cannot be undone.",
"storage.cleanup.quarantineNote": "Files move to .trash under CODEX_HOME. There is no in-app restore in this release — keep the trash folder, or manually move files back using manifest.json.",
"storage.cleanup.cancel": "Cancel",
"storage.cleanup.confirmQuarantine": "Quarantine",
"storage.cleanup.confirmPermanent": "Delete permanently",
"storage.cleanup.doneQuarantine": "Quarantined {count} file(s) ({size}).",
"storage.cleanup.donePermanent": "Permanently deleted {count} file(s) ({size}).",
"storage.cleanup.previewFailed": "Preview failed.",
"storage.cleanup.cleanupFailed": "Cleanup failed.",
"storage.cleanup.err.codex_busy": "Codex is using state.sqlite — try again after quitting Codex.",
"storage.cleanup.err.stale_preview": "Archived files changed since preview — run Preview again.",
"storage.cleanup.err.referenced_history": "Selected archives are still referenced by forked or paginated history.",
"storage.cleanup.err.invalid_digest": "Preview digest is missing or invalid.",
"storage.cleanup.err.invalid_mode": "Cleanup mode must be quarantine or permanent.",
"storage.cleanup.err.fs_failed": "Filesystem cleanup failed. Some changes may already be applied — check CODEX_HOME/.trash and any recovery path shown.",
"storage.cleanup.err.fs_failed_trash": "Filesystem cleanup failed. Some changes may already be applied — check {trashDir} and manifest.json for recoverable files.",
"storage.cleanup.err.db_reconcile_failed": "Could not update Codex state database.",
"storage.cleanup.err.cleanup_failed": "Cleanup failed.",

// add-provider modal
"modal.addNamed": "Add: {label}",
Expand Down
30 changes: 29 additions & 1 deletion gui/src/i18n/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ export const ja: Record<TKey, string> = {

"nav.storage": "ストレージ",
"storage.title": "ストレージ",
"storage.subtitle": "CODEX_HOME ディスクの使用先の読み取り専用ビューです。このページでは何も削除しません。",
"storage.subtitle": "CODEX_HOME のディスク使用診断。下のアーカイブクリーンアップで古いアーカイブを隔離または完全削除できます — アクティブセッションは読み取り専用のままです。",
"storage.loading": "ストレージをスキャン中…",
"storage.empty": "CODEX_HOME が空か存在しません — 報告するものはありません。",
"storage.error": "ストレージのスキャンに失敗しました。CODEX_HOME が有効なディレクトリを指しているか確認してください。",
Expand All @@ -601,6 +601,34 @@ export const ja: Record<TKey, string> = {
"storage.bucket.attachments": "添付",
"storage.bucket.deletion_manifests": "削除マニフェスト",
"storage.bucket.other": "その他",
"storage.cleanup.title": "アーカイブのクリーンアップ",
"storage.cleanup.help": "古いアーカイブセッションを割合で削除します。アクティブセッションには触れません。既定は隔離で、ファイルは CODEX_HOME/.trash へ移動します。",
"storage.cleanup.slider": "古いアーカイブの割合",
"storage.cleanup.percent": "古い {percent}%",
"storage.cleanup.preset": "{percent}",
"storage.cleanup.preview": "プレビュー",
"storage.cleanup.confirmTitle": "アーカイブクリーンアップの確認",
"storage.cleanup.confirmBody": "アーカイブ {count} 件(約 {size})、古い {percent}% を処理します。",
"storage.cleanup.moreFiles": "…ほか {n} 件",
"storage.cleanup.permanent": "完全に削除する(隔離しない)",
"storage.cleanup.permanentWarn": "完全削除は元に戻せません。",
"storage.cleanup.quarantineNote": "ファイルは CODEX_HOME 下の .trash へ移動します。この版にアプリ内復元はありません — ゴミ箱を残すか、manifest.json を使って手動で戻してください。",
"storage.cleanup.cancel": "キャンセル",
"storage.cleanup.confirmQuarantine": "隔離する",
"storage.cleanup.confirmPermanent": "完全に削除",
"storage.cleanup.doneQuarantine": "{count} 件を隔離しました({size})。",
"storage.cleanup.donePermanent": "{count} 件を完全削除しました({size})。",
"storage.cleanup.previewFailed": "プレビューに失敗しました。",
"storage.cleanup.cleanupFailed": "クリーンアップに失敗しました。",
"storage.cleanup.err.codex_busy": "Codex が state.sqlite を使用中です — Codex を終了して再試行してください。",
"storage.cleanup.err.stale_preview": "プレビュー以降にアーカイブが変わりました — プレビューをやり直してください。",
"storage.cleanup.err.referenced_history": "選択したアーカイブはフォークまたはページング履歴から参照されています。",
"storage.cleanup.err.invalid_digest": "プレビューのダイジェストが無い、または無効です。",
"storage.cleanup.err.invalid_mode": "モードは quarantine または permanent である必要があります。",
"storage.cleanup.err.fs_failed": "ファイルシステムのクリーンアップに失敗しました。一部の変更は既に適用されている可能性があります — CODEX_HOME/.trash と表示されたリカバリパスを確認してください。",
"storage.cleanup.err.fs_failed_trash": "ファイルシステムのクリーンアップに失敗しました。一部の変更は既に適用されている可能性があります — {trashDir} と manifest.json で復旧可能なファイルを確認してください。",
"storage.cleanup.err.db_reconcile_failed": "Codex の状態データベースを更新できませんでした。",
"storage.cleanup.err.cleanup_failed": "クリーンアップに失敗しました。",

// add-provider modal
"modal.addNamed": "追加: {label}",
Expand Down
Loading
Loading