Skip to content

feat: session filter restore, error nav, large-file mode, backend filtering, logging, CSP hardening#201

Open
adamgell wants to merge 2 commits into
mainfrom
agents/code-review-session-improvements
Open

feat: session filter restore, error nav, large-file mode, backend filtering, logging, CSP hardening#201
adamgell wants to merge 2 commits into
mainfrom
agents/code-review-session-improvements

Conversation

@adamgell

@adamgell adamgell commented May 23, 2026

Copy link
Copy Markdown
Owner
  • Confirm actionable review comments and target files
  • Run baseline lint/build/tests before edits
  • Apply minimal code fixes for all requested comments
  • Run targeted tests for changed areas
  • Run final validation (Code Review + CodeQL)
  • Reply to addressed @copilot comments with commit hash

…tering, logging, CSP hardening

Seven application-level improvements from static code review:

fix(session): restore FilterClause[] into useFilterStore on session open
- session.ts validates clauses as typed FilterClause[]
- session-restore.ts calls setClauses() after files load; AppShell re-applies naturally
- Regression tests: src/lib/session.test.ts, src/lib/session-restore.test.ts

feat(logging): add tauri-plugin-log + open logs folder (resolves #193)
- Initialized tauri-plugin-log in lib.rs; logs written to platform log dir
- app_config.rs: open_app_logs_folder IPC command
- AboutDialog: 'Open Logs Folder' button and test coverage

feat(nav): next/previous error navigation (F8 / Shift+F8)
- Toolbar Prev/Next Error buttons; disabled in large-file mode
- log-store: navigates filtered visible-row order, wraps at boundaries
- use-keyboard: F8/Shift+F8 shortcuts

feat(perf): large-file mode (>50 MB threshold)
- Backend detects large files in file_ops.rs; emits LargeFileModeInfo metadata
- Frontend disables sort, auto-fit, full-text find; shows inline banner + status badge
- tab-snapshot-cache preserves large-file mode across tab switches

feat(perf): backend session-keyed filtering
- AppState holds parsed-entry registry (HashMap<String, Vec<LogEntry>>)
- apply_filter accepts optional sessionKey; falls back to raw entries if stale
- filter-store: mergeFilteredIds for incremental live-tail appends
- AppShell dispatches session-keyed filter; merges new tail rows incrementally

fix(security): replace null CSP with restrictive content security policy
- tauri.conf.json: default-src 'self'; img-src asset: data:; style-src 'unsafe-inline'
- dev bundle adds script-src 'unsafe-eval' for Vite HMR

ci: add Playwright smoke tests to CI frontend job
- e2e/smoke.spec.ts tightened with deterministic assertions
- cmtrace-ci.yml runs npm run test:e2e after Vitest

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 23, 2026 03:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR delivers a set of end-to-end improvements across the CMTrace Open Tauri backend and React frontend, focused on session persistence (filters), usability for troubleshooting (error navigation), performance safeguards for large logs, backend-assisted filtering, and operational hardening (logging, CSP, CI smoke tests).

Changes:

  • Fixes session restore so saved filter clauses are validated/sanitized and re-applied after files load, with new regression tests.
  • Adds large-file mode metadata from the backend and disables expensive UI features (find/sort/autofit/filtering) to protect responsiveness; introduces Next/Prev Error navigation.
  • Introduces backend session-keyed filtering plumbing plus application logging (“Open Logs Folder”), CSP hardening, and Playwright smoke tests in CI.

Reviewed changes

Copilot reviewed 32 out of 32 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
.github/workflows/cmtrace-ci.yml Adds Playwright install + e2e smoke test run in CI.
e2e/smoke.spec.ts Makes smoke tests more deterministic (shared open helper, tighter assertions).
src-tauri/Cargo.toml Adds tauri-plugin-log dependency.
src-tauri/src/lib.rs Initializes log plugin, emits startup/log-dir diagnostics, registers new IPC commands.
src-tauri/src/state/app_state.rs Adds parsed-entry session registry in app state (register/get/release).
src-tauri/src/commands/app_config.rs Adds open_app_logs_folder command to open platform log directory in file manager.
src-tauri/src/commands/file_ops.rs Adds large-file mode evaluation/metadata and wraps parse responses with backend session metadata.
src-tauri/src/commands/filter.rs Updates apply_filter to accept optional session key and resolve entries via AppState.
src-tauri/src/parser/dns_audit.rs Ensures parse results include large_file_mode: None and tweaks logging/formatting.
src-tauri/tauri.conf.json Replaces null CSP with restrictive production + dev CSP policies.
crates/cmtraceopen-parser/src/models/log_entry.rs Adds LargeFileModeMetadata and optional large_file_mode fields to parse results.
crates/cmtraceopen-parser/src/parser/mod.rs Sets default large_file_mode: None in parser output.
src/stores/log-store.ts Adds large-file mode state, visible error navigation state, and disables find when large-file mode is active.
src/stores/log-store.test.ts Adds tests for large-file mode state and visible error navigation behavior.
src/stores/filter-store.ts Adds backend filter invocation helper, session-key fallback behavior, and mergeFilteredIds.
src/stores/filter-store.test.ts Adds tests for backend filtering behavior (session key, fallback, forced raw entries) and merge helper.
src/lib/commands.ts Normalizes wrapped backend parse responses; adds parsed-entry session + open logs folder commands.
src/lib/log-source.ts Propagates backend session keys into sources, caches large-file mode, and registers aggregate sessions.
src/lib/session.ts Sanitizes/restores typed filter clauses from saved sessions; refactors filter validation.
src/lib/session.test.ts New tests validating filter clause sanitization/back-compat in sessions.
src/lib/session-restore.ts Restores filter clauses via filter-store after file load (alongside find/highlight state).
src/lib/session-restore.test.ts New tests verifying filter clause restore timing and sanitization behavior.
src/lib/tab-snapshot-cache.ts Extends cached tab snapshots with large-file mode metadata.
src/components/dialogs/AboutDialog.tsx Adds “Open Logs Folder” action with user-friendly error display.
src/components/dialogs/AboutDialog.test.tsx Adds tests for the new logs folder action and error handling.
src/components/layout/AppShell.tsx Moves filtering to backend helper, supports incremental tail filtering, disables filtering in large-file mode.
src/components/layout/FindBar.tsx Disables find UI/actions in large-file mode and adds explanatory tooltips/message.
src/components/layout/StatusBar.tsx Shows large-file mode badge and status text when active.
src/components/layout/Toolbar.tsx Adds Prev/Next Error actions and refines filter button tooltip/disable messaging.
src/components/log-view/LogListView.tsx Disables sorting/autofit in large-file mode; reports visible IDs to enable error navigation.
src/hooks/use-keyboard.ts Adds F8 / Shift+F8 keyboard shortcuts for error navigation gated by command state.
src/types/log.ts Adds TS types for backend session metadata and large-file mode metadata on parse results/sources.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +115 to +120
function getErrorNavigationDisabledReason(
activeView: WorkspaceId,
isLoading: boolean,
entriesCount: number,
visibleErrorEntryCount: number
): string | null {
lastAppliedSignatureRef.current = null;
appliedFilterSnapshotRef.current = null;
setFilteredIds(null);
setIsFiltering(false);
Comment on lines +117 to +121

fn register_parsed_entries_backend_session(
state: &AppState,
entries: &[LogEntry],
) -> Result<Option<ParsedEntriesSessionMetadata>, crate::error::AppError> {
Comment on lines +92 to +96

Ok(sessions
.get(session_key)
.map(|session| session.entries.clone()))
}
Comment thread src/stores/log-store.ts
Comment on lines +249 to +253
if (direction === "next") {
for (const errorId of state.visibleErrorEntryIds) {
if (state.visibleEntryIds.indexOf(errorId) > selectedVisibleIndex) {
return errorId;
}

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 32 out of 32 changed files in this pull request and generated 6 comments.

Comment on lines +390 to +392
let backend_session =
register_parsed_entries_backend_session(state.inner(), &result.entries)?;

Comment thread src/lib/log-source.ts
Comment on lines +456 to +463
const aggregateView = buildAggregateView(allResults);
const backendSession = await registerAggregateEntriesSession(
aggregateView.allEntries
);
const sourceWithSession = withSourceSessionKeys(source, {
sessionKey: null,
aggregateSessionKey: backendSession?.sessionKey ?? null,
});
Comment thread src/lib/log-source.ts
Comment on lines +315 to +318
const sourceWithSession = withSourceSessionKeys(source, {
sessionKey: result.backendSession?.sessionKey ?? null,
});
state.setActiveSource(sourceWithSession);
Comment on lines +53 to +57
function buildClauseSignature(clauses: FilterClause[]): string {
return clauses
.map((clause) => `${clause.field}:${clause.op}:${clause.value}`)
.join("|");
}
Comment on lines +128 to +136
const appendedEntries = entries.filter((entry) => entry.id > appliedSnapshot.maxEntryId);

if (appendedEntries.length === 0) {
return null;
}

return appliedSnapshot.entryCount + appendedEntries.length === entries.length
? appendedEntries
: null;
tags: None,
}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants