Skip to content

Commit 7ca1d45

Browse files
committed
fix: bound session management reads
1 parent 82b8ab5 commit 7ca1d45

5 files changed

Lines changed: 948 additions & 69 deletions

File tree

.agents/skills/gettokens-domain-engineering/SKILL.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,13 @@ This skill unifies the technical rules for building, styling, and debugging GetT
142142
- Frontend Usage Desk rendering must branch by `source === 'observed'` vs `source === 'projected'`, not by workspace. A workspace-specific override such as `workspace === 'claude'` inside the observed branch can make a projected button visually selected while still rendering observed data.
143143
- `usage-local:*` events must carry and filter `provider`, so Codex rollout projection and Claude session projection do not overwrite each other's page state.
144144
- Verification for this class of change must include fixture tests, generated binding assertions, preview projected rows, and a real local-file sanity check that reports counts/totals without reading or printing sensitive message content.
145+
- **Session Management Local Files**:
146+
- Treat `~/.codex/sessions`, `~/.codex/archived_sessions`, and `~/.claude/projects` as potentially multi-GB local stores. Never make page entry depend on synchronous full-file parsing when a bounded snapshot or stale cache can satisfy the first paint.
147+
- Snapshot/list APIs should return summaries only. Do not carry full message bodies, raw tool payloads, or per-message `content` through snapshot DTOs.
148+
- Detail APIs used by the UI must be payload-bounded. Keep full parsing inside backend-only analysis paths when needed, but UI detail responses should prefer summary rows, cap message count, and avoid returning full `content` unless a scoped requirement explicitly needs it.
149+
- Any in-process cache for session details must have both entry-count and approximate-byte limits. Oversized details should use disk cache only, not stay resident in `App`.
150+
- Disk caches must invalidate by file fingerprint such as size plus mtime. Do not use session id alone as a cache key for mutable JSONL files.
151+
- Regression coverage for this class should include cache hit, stale-cache invalidation, payload compaction, memory-bound eviction, and at least one live benchmark path gated by an explicit environment variable so CI never reads a developer's real sessions.
145152
- **Codex Live Sessions**: For `#frame=codex&workspace=live-sessions`, treat the feature as runtime observability, not local session-file management. Use this when surfacing in-flight request/session state from CLIProxyAPI.
146153
- Data ownership starts in the CLIProxyAPI fork. Add an in-memory runtime tracker and a read-only management endpoint first; then expose it through `internal/wailsapp`, root `main.App`, generated `frontend/wailsjs`, and finally the React feature.
147154
- Keep the UI read-only. Do not add request cancel, replay, forced WebSocket recovery, or full payload display unless a later requirement explicitly scopes the action and safety model.

frontend/src/features/session-management/SessionManagementFeature.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,10 @@ export default function SessionManagementFeature({ workspace = 'codex' }: Sessio
263263
],
264264
);
265265

266+
if (snapshotLoading && !projects.length && !snapshotError) {
267+
return <InitialLoadingShell copy={copy} />;
268+
}
269+
266270
return (
267271
<section className="flex h-full min-h-0 flex-col bg-[var(--bg-surface)] px-6 py-6 text-[var(--text-primary)] select-text">
268272
<WorkspacePageHeader

internal/wailsapp/app.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,12 @@ type localUsageRuntimeState struct {
4545
}
4646

4747
type sessionManagementRuntimeState struct {
48-
cachedSnapshot *SessionManagementSnapshot
49-
cachedAt time.Time
50-
refreshRunning bool
48+
cachedSnapshot *SessionManagementSnapshot
49+
cachedAt time.Time
50+
refreshRunning bool
51+
cachedDetails map[string]*sessionManagementDetailCacheEntry
52+
cachedDetailOrder []string
53+
cachedDetailBytes int
5154
}
5255

5356
type sidecarRequestFunc func(method string, path string, query url.Values, body io.Reader, contentType string) ([]byte, int, error)

0 commit comments

Comments
 (0)