Skip to content

feat: pluggable workspace registry system - #84

Merged
adamgell merged 68 commits into
mainfrom
refactor/workspace-registry
Apr 6, 2026
Merged

feat: pluggable workspace registry system#84
adamgell merged 68 commits into
mainfrom
refactor/workspace-registry

Conversation

@adamgell

@adamgell adamgell commented Apr 5, 2026

Copy link
Copy Markdown
Owner

Summary

  • Workspace registry: Centralized, type-safe WorkspaceDefinition system that replaces 25+ scattered if/else chains across AppShell, Toolbar, FileSidebar, and ui-store
  • 6 workspaces fully migrated to self-contained folders under src/workspaces/ (sysmon, dsregcmd, event-log, macos-diag, deployment, intune)
  • Shared component extraction: SourceSummaryCard and sidebar primitives deduplicated to src/components/common/sidebar-primitives.tsx; getBaseName consolidated to single canonical export
  • Adding a new workspace now requires one folder + one import in the registry — no more touching 8+ files

What changed

New: Workspace Registry (src/workspaces/)

  • types.tsWorkspaceDefinition interface with capabilities, file filters, action labels, status labels, onOpenSource handlers
  • registry.ts — Central Map<WorkspaceId, WorkspaceDefinition> with getWorkspace() and getAvailableWorkspaces()
  • Per-workspace folders containing components, stores, types, sidebars, and definitions

Removed: Scattered workspace branching

  • WORKSPACE_PLATFORM_MAP in ui-store — deleted, delegates to registry
  • WORKSPACE_LABELS, getOpenFileDialogFilters(), getOpenActionLabels() in Toolbar — deleted
  • getUiChromeStatus() — 8-way if/else replaced with 2-way capability check
  • openSourceForWorkspace() — 5-way if/else replaced with workspace.onOpenSource lookup
  • renderWorkspace() in AppShell — 8-way if/else replaced with registry lookup + Suspense
  • Sidebar routing in FileSidebar — 4-way ternary replaced with registry lookup
  • commandState capability checks — workspace ID checks replaced with capabilities.* flags

Test plan

  • npx tsc --noEmit passes
  • npm run frontend:build succeeds
  • Each workspace loads correctly: log, intune, new-intune, dsregcmd, sysmon, event-log, macos-diag, deployment
  • File open dialogs show correct filters per workspace
  • Sidebar renders correctly for each workspace
  • Status bar labels display correctly per workspace
  • Platform gating works (dsregcmd/sysmon/deployment Windows-only, macos-diag macOS-only)

🤖 Generated with Claude Code

adamgell and others added 30 commits April 2, 2026 17:53
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…controls

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…nd bar to log view

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…angelog

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…performance

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…leanup

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Introduce end-to-end Microsoft Graph integration to resolve Intune app GUIDs. Backend: new src-tauri/src/graph_api.rs implements WAM-based Windows auth, token caching, batch/single Graph requests, paginated app fetches and an in-memory GUID cache; adds fetch_all_apps and resolve_guids utilities. Frontend: new GraphApiTab settings UI to enable/sign-in/pre-populate cache, a startup hook to auto-connect and populate cache, status bar indicator for Graph status, and enhancements to the GUID registry dialog (tabs, filtering, publisher/type columns). Add lib/graph-registry.ts to convert GraphAppInfo to GuidRegistry entries and update types (GuidCategory, publisher). Also improve event_tracker to extract PolicyId from JSON payloads. Wire startup import in main.tsx and add ui-store state/handlers for graphApiEnabled and graphApiStatus.
Add opt-in Graph API support to resolve Intune app GUIDs to display
names using the device's existing Entra ID session via WAM (Web Account
Manager). No app registration required — uses the Microsoft Graph
PowerShell public client ID.

- WAM authentication with HWND interop for Win32 desktop apps
- Graph API client with batch resolution ($batch endpoint, 20 per request)
- Pre-populate cache button fetches all tenant apps in one call
- GraphApi source variant (highest confidence) in GuidRegistry
- Settings tab with opt-in toggle (off by default), consent warnings,
  and connection status display
- Automatic enrichment during Intune log analysis when enabled

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix analyze_intune_logs to use app.state() instead of cfg-gated parameter
  (Tauri generate_handler! can't handle #[cfg] on parameters)
- Gate Manager import to windows-only in both lib.rs and intune.rs
- Resolve merge conflicts in ui-store.ts (recentSessions + graphApi state)
- Resolve merge conflicts in GraphApiTab.tsx (keep buildGraphRegistryEntries)
- Fix GuidRegistryDialog aria-label to use entry.guid

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…tion refresh, diff close

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Resolve lib.rs conflict (keep both Graph API + Sysmon commands)
- Add verbose Sysmon workspace entry to changelog

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
adamgell and others added 22 commits April 5, 2026 19:04
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
6 tasks: shim definitions, AppShell/FileSidebar/ui-store/Toolbar refactors

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Creates shim WorkspaceDefinition objects for the 7 remaining workspaces
(log, intune, new-intune, dsregcmd, macos-diag, deployment, event-log),
exports LogSidebar/IntuneSidebar/DsregcmdSidebar from FileSidebar.tsx,
and registers all 8 workspaces in the workspace registry.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the 8-way if/else chain in renderWorkspace() with a registry
lookup + Suspense for all non-log workspaces. Log workspace inline
rendering (DiffView, RegistryViewer, folder overlay, InfoPane) is
preserved as a special case. TabStrip and FindBar conditionals now
consult workspace capabilities flags instead of hard-coding activeView.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the ternary chain (isIntuneWorkspace / activeView === 'sysmon'
checks) with a registry lookup via getWorkspace(activeView).sidebar, and
drive the footer bar from capabilities.footerBar. Remove now-unused
SysmonSidebar direct import and isIntuneWorkspace import.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove WORKSPACE_PLATFORM_MAP constant and inline filter logic from
getAvailableWorkspaces(). Delegate to getRegistryWorkspaces() from
the workspace registry instead, mapping WorkspaceDefinition[] back
to WorkspaceId[] to preserve the existing public API surface.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace WORKSPACE_LABELS, getOpenFileDialogFilters(), and
getOpenActionLabels() with direct lookups from getWorkspace() in the
workspace registry, eliminating ~75 lines of duplicated metadata.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move all dsregcmd-specific files into src/workspaces/dsregcmd/ to make
the workspace fully self-contained, following the same pattern as sysmon.

- git mv types/dsregcmd.ts → workspaces/dsregcmd/types.ts
- git mv stores/dsregcmd-store.ts → workspaces/dsregcmd/dsregcmd-store.ts
- git mv components/dsregcmd/* → workspaces/dsregcmd/ (7 files)
- Extract DsregcmdSidebar from FileSidebar.tsx into workspaces/dsregcmd/DsregcmdSidebar.tsx
- Update index.ts shim to use local ./ imports
- Update all external importers (Toolbar, StatusBar, EvidenceBundleDialog,
  commands.ts, dsregcmd-source.ts, dsregcmd-store.test.ts, event-log/index.ts)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move types, store, and all 7 components out of src/types/, src/stores/,
and src/components/event-log-workspace/ into the unified workspace directory.
Update all internal imports to use relative paths within the workspace.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move types, store, and all 9 components from their scattered locations
(src/types/, src/stores/, src/components/macos-diag/) into the unified
workspace directory src/workspaces/macos-diag/. Update all internal
and external import paths accordingly. TypeScript passes clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Moves deployment-store.ts and all 3 component files (DeploymentWorkspace,
DeploymentErrorCard, DeploymentSuccessTable) from their legacy locations into
src/workspaces/deployment/. Updates all import paths in the moved files,
the workspace index shim, StatusBar.tsx, and both dynamic imports in Toolbar.tsx.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Moves all 19 intune components, the intune store (1,095 lines), types,
hook, and test file from their scattered locations into the consolidated
src/workspaces/intune/ directory. Extracts IntuneSidebar from
FileSidebar.tsx into its own file with helpers inlined. Updates all
importers across layout, dialogs, hooks, and lib modules. Both the
intune and new-intune workspace shims now reference local workspace paths.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…getBaseName

- Create src/components/common/sidebar-primitives.tsx with SourceSummaryCard,
  SourceStatusNotice, SectionHeader, EmptyState, and SidebarActionButton
- Remove inline copies of all five components from FileSidebar, IntuneSidebar,
  DsregcmdSidebar, and SysmonSidebar; import from shared module instead
- Widen canonical getBaseName signature to string | null | undefined
- Remove exported getBaseName from log-store; import from file-paths instead
- Update all callers in log-source, dsregcmd-source, EvidenceBundleDialog,
  StatusBar, IntuneSidebar, SysmonSidebar, and FileSidebar to use file-paths
- Also removes local getDirectoryName copy from EvidenceBundleDialog

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…stry lookup

Add statusLabel to WorkspaceDefinition; set overrides on log, intune, and
new-intune workspaces. getUiChromeStatus now resolves labels via getWorkspace()
and branches only on capabilities.detailsPane, eliminating the 8-way if/else.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…mmandState

Move workspace-specific analysis logic (intune, dsregcmd, sysmon, deployment)
from Toolbar.tsx into each workspace's onOpenSource in its definition. Replace
the openSourceForWorkspace if/else chain with a registry lookup. Add knownSources
and tailing to WorkspaceCapabilities and use them in commandState instead of
hardcoded workspace ID checks.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 5, 2026 23:07

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 introduces a centralized, typed workspace registry (WorkspaceDefinition + registry map) and migrates multiple workspaces to self-contained folders under src/workspaces/, replacing scattered workspace-specific branching across the UI. It also includes several adjacent feature additions/refactors (workspace-specific sidebars, Graph API integration hooks/commands, session save/restore, and log merge/diff utilities/UI) that touch both the frontend and Tauri backend.

Changes:

  • Added a pluggable workspace registry (src/workspaces/types.ts, src/workspaces/registry.ts) and migrated workspaces (log/intune/new-intune/dsregcmd/macos-diag/deployment/event-log/sysmon) to the new structure.
  • Introduced shared sidebar primitives and new workspace-specific sidebars (e.g., Intune/Dsregcmd/Sysmon).
  • Added supporting features/utilities across the app: Graph API integration plumbing, session save/restore file format + commands, and merge/diff helpers and UI components.

Reviewed changes

Copilot reviewed 142 out of 155 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/workspaces/types.ts Adds core WorkspaceDefinition and capability/filter/action-label typing.
src/workspaces/registry.ts Central registry + platform/enabled filtering helpers.
src/workspaces/log/index.ts Registers Log Explorer workspace definition + capabilities/filters.
src/workspaces/intune/index.ts Registers Intune workspace + shared createIntuneOnOpenSource handler (incl. Graph toggle).
src/workspaces/new-intune/index.ts Registers “new-intune” workspace pointing at Intune components/handlers.
src/workspaces/intune/types.ts Moves/extends Intune workspace types (GUID registry GraphApi source + metadata).
src/workspaces/intune/intune-store.ts Migrates Intune store into workspace folder; adds mergeGuidRegistry.
src/workspaces/intune/intune-store.test.ts Adds Intune store unit tests (Vitest).
src/workspaces/intune/use-intune-analysis-progress.ts Updates imports to new workspace-local store/types.
src/workspaces/intune/useTimeWindowFilter.ts Updates imports to new workspace-local store/types.
src/workspaces/intune/SummaryView.tsx Updates imports to new workspace-local store/types.
src/workspaces/intune/SummaryViewComponents.tsx Updates imports to new workspace-local types.
src/workspaces/intune/summary-view-logic.ts Updates imports to new workspace-local types.
src/workspaces/intune/OverviewSurface.tsx Updates store import location for event-log ID lookup.
src/workspaces/intune/NewIntuneWorkspace.tsx Updates toolbar hook import path + store import.
src/workspaces/intune/InvestigationPanel.tsx Updates imports to new workspace-local types.
src/workspaces/intune/IntuneDashboard.tsx Updates store import location.
src/workspaces/intune/IntuneDashboardHeader.tsx Updates toolbar hook import path + store import.
src/workspaces/intune/IntuneDashboardNavBar.tsx Updates store/types imports to workspace-local paths.
src/workspaces/intune/IntuneSidebar.tsx Adds new Intune workspace sidebar built on shared primitives.
src/workspaces/intune/EventTimeline.tsx Updates store/types imports to workspace-local paths.
src/workspaces/intune/EventTimelineRow.tsx Updates types import to workspace-local types.
src/workspaces/intune/EventTimelineRow.test.tsx Updates types import to workspace-local types.
src/workspaces/intune/EventActivityView.tsx Updates store/types imports; improves GUID lookup fallback behavior.
src/workspaces/intune/DownloadSurface.tsx Updates types import to workspace-local types.
src/workspaces/intune/DownloadStats.tsx Updates store/types imports to workspace-local paths.
src/workspaces/intune/EventLogSurface.tsx Updates store import location to workspace-local store.
src/workspaces/intune/intune-dashboard-utils.ts Updates types import; switches non-nullable type import target to workspace-local types.
src/workspaces/sysmon/index.ts Registers Sysmon workspace definition + lazy component/sidebar + open handler.
src/workspaces/sysmon/types.ts Adds Sysmon workspace-local types (events/summary/dashboard/config).
src/workspaces/sysmon/sysmon-store.ts Updates Sysmon store types import to workspace-local types.
src/workspaces/sysmon/use-sysmon-analysis-progress.ts Updates import path to workspace-local sysmon-store.
src/workspaces/sysmon/SysmonWorkspace.tsx Updates store import path + toolbar hook import path.
src/workspaces/sysmon/SysmonEventTable.tsx Updates store/types import paths to workspace-local types.
src/workspaces/sysmon/SysmonDashboardView.tsx Updates store import path to workspace-local sysmon-store.
src/workspaces/sysmon/SysmonSummaryView.tsx Updates store import path to workspace-local sysmon-store.
src/workspaces/sysmon/SysmonConfigView.tsx Updates store import path to workspace-local sysmon-store.
src/workspaces/sysmon/SysmonSidebar.tsx Adds Sysmon-specific sidebar using shared primitives.
src/workspaces/sysmon/DashboardMetricCards.tsx Updates Sysmon types import to workspace-local types.
src/workspaces/sysmon/DashboardEventTypeChart.tsx Updates Sysmon types import to workspace-local types.
src/workspaces/sysmon/DashboardTimeline.tsx Updates Sysmon types import to workspace-local types.
src/workspaces/sysmon/DashboardSecurityAlerts.tsx Updates Sysmon types import to workspace-local types.
src/workspaces/sysmon/DashboardTopList.tsx Updates Sysmon types import to workspace-local types.
src/workspaces/macos-diag/index.ts Registers macOS diagnostics workspace definition.
src/workspaces/macos-diag/types.ts Adds macOS diagnostics workspace-local types.
src/workspaces/macos-diag/macos-diag-store.ts Updates types import to workspace-local types.
src/workspaces/macos-diag/MacosDiagWorkspace.tsx Updates store import path to workspace-local store.
src/workspaces/macos-diag/MacosDiagUnifiedLogTab.tsx Updates store import path to workspace-local store.
src/workspaces/macos-diag/MacosDiagTabStrip.tsx Updates store/types import paths to workspace-local paths.
src/workspaces/macos-diag/MacosDiagProfilesTab.tsx Updates store import path to workspace-local store.
src/workspaces/macos-diag/MacosDiagPackagesTab.tsx Updates store import path to workspace-local store.
src/workspaces/macos-diag/MacosDiagIntuneLogsTab.tsx Updates store/types import paths to workspace-local paths.
src/workspaces/macos-diag/MacosDiagEnvironmentBanner.tsx Updates types import to workspace-local types.
src/workspaces/macos-diag/MacosDiagDefenderTab.tsx Updates store/types import paths to workspace-local paths.
src/workspaces/macos-diag/MacosDiagFdaGuide.tsx Adds FDA guidance UI (invokes backend command to open settings if available).
src/workspaces/dsregcmd/index.ts Registers dsregcmd workspace definition + onOpenSource behavior.
src/workspaces/dsregcmd/types.ts Adjusts EventLogAnalysis type reference to shared src/types/event-log.
src/workspaces/dsregcmd/dsregcmd-store.ts Moves dsregcmd store under workspace; updates type imports.
src/workspaces/dsregcmd/DsregcmdWorkspace.tsx Updates store import path + toolbar hook import path.
src/workspaces/dsregcmd/DsregcmdEventLogSurface.tsx Updates store import path to workspace-local dsregcmd-store.
src/workspaces/dsregcmd/dsregcmd-formatters.ts Updates types import to workspace-local dsregcmd types.
src/workspaces/dsregcmd/fact-group-builders.ts Updates types import to workspace-local dsregcmd types.
src/workspaces/dsregcmd/DiagnosticInsightsCard.tsx Updates types import to workspace-local dsregcmd types.
src/workspaces/dsregcmd/PolicyEvidencePane.tsx Adds UI primitives for dsregcmd evidence/policy rendering.
src/workspaces/dsregcmd/FactGroupRenderer.tsx Adds table renderer for dsregcmd fact groups.
src/workspaces/dsregcmd/DsregcmdSidebar.tsx Adds dsregcmd-specific sidebar using shared primitives.
src/workspaces/deployment/index.ts Registers deployment workspace definition + open handler.
src/workspaces/deployment/deployment-store.ts Adds deployment analysis store + backend invoke plumbing.
src/workspaces/deployment/DeploymentWorkspace.tsx Updates store import path to workspace-local deployment-store.
src/workspaces/deployment/DeploymentErrorCard.tsx Updates store import path to workspace-local deployment-store.
src/workspaces/deployment/DeploymentSuccessTable.tsx Updates store import path to workspace-local deployment-store.
src/workspaces/event-log/index.ts Registers event-log workspace definition (currently miswired sidebar/filters).
src/workspaces/event-log/types.ts Extends EVTX parse result type to include errorMessages.
src/workspaces/event-log/SourcePicker.tsx Updates store import path to workspace-local evtx-store.
src/workspaces/event-log/EvtxTimeline.tsx Adds keyboard navigation + focusable listbox container; adjusts styles.
src/workspaces/event-log/EvtxTimelineRow.tsx Updates types import to workspace-local event-log types.
src/workspaces/event-log/EvtxFilterBar.tsx Updates store/types imports to workspace-local event-log files.
src/workspaces/event-log/EvtxDetailPane.tsx Updates store import path; adjusts message panel sizing.
src/workspaces/event-log/EventLogWorkspace.tsx Adds updated event-log workspace layout with resizable detail pane + progress bar.
src/workspaces/event-log/evtx-store.ts Adds/relocates EVTX Zustand store; adds progress listener (currently module-scoped).
src/types/event-log.ts Changes IntuneTimestampBounds import target to workspace Intune types.
src/stores/ui-store.ts Replaces workspace platform map with registry lookups; adds new UI flags/persisted fields.
src/stores/evtx-store.ts Removes old top-level EVTX store (moved under workspace).
src/stores/dsregcmd-store.test.ts Updates dsregcmd-store test import path to workspace-local store.
src/main.tsx Imports Graph API startup module.
src/hooks/use-graph-api-startup.ts Adds persist-hydration-triggered Graph auto-connect + GUID registry merge.
src/hooks/use-app-menu.ts Adds menu actions for session save/open.
src/lib/commands.ts Updates types import targets; adds Graph API commands + graphApiEnabled option for Intune analysis.
src/lib/graph-registry.ts Adds helper to convert Graph app info into GUID registry entries.
src/lib/session.ts Defines session file format + validation/sanitization.
src/lib/session-save.ts Implements session save flow (hash via backend, persist recent sessions).
src/lib/session-restore.ts Implements session restore flow + integrity checks + state restoration.
src/lib/merge-entries.ts Adds merge helpers (color assignment, merge, correlation helpers).
src/lib/diff-entries.ts Adds diff normalization/classification helpers.
src/lib/log-source.ts Removes local getBaseName helper; uses shared file-paths export.
src/lib/file-paths.ts Broadens getBaseName input type to allow undefined.
src/lib/dsregcmd-source.ts Moves dsregcmd type/store imports; uses shared getBaseName.
src/lib/profile-utils.ts Updates macOS profile type import to workspace-local types.
src/lib/intune-sort.ts Updates imports for Intune types/store to workspace-local paths.
src/components/common/sidebar-primitives.tsx Adds shared sidebar primitive components for workspace sidebars.
src/components/dialogs/SettingsDialog.tsx Adds Graph API settings tab (Windows-only).
src/components/dialogs/MergeTabsDialog.tsx Adds UI for selecting tabs to merge into unified timeline.
src/components/dialogs/DiffConfigDialog.tsx Adds UI for selecting two tabs to compare.
src/components/dialogs/EvidenceBundleDialog.tsx Updates store imports; replaces local path helpers with shared file-paths utilities.
src/components/log-view/MergeLegendBar.tsx Adds legend/toggles for merged timeline mode.
src/components/log-view/DiffHeader.tsx Adds diff mode header with stats + display toggle + close action.
src/components/log-view/LogRow.tsx Adds merge stripe + correlation highlight styling inputs.
src/components/log-view/LogListView.tsx Integrates MergeLegendBar and correlated highlighting in merged mode.
src/components/log-view/InfoPane.tsx Adds correlated-entries section for merged mode; uses fileBaseName helper.
src/components/log-view/AppWorkloadScriptDetail.tsx Fixes UTF-8 base64 decode; tightens GetPolicies parsing types.
src/components/layout/TabStrip.tsx Adds merged/diff close behavior + merged-tab labeling.
src/components/layout/StatusBar.tsx Adds Graph API status indicator + EVTX status summary + tiny spinner.
src/components/event-log-workspace/EventLogWorkspace.tsx Removes old event-log workspace component (moved to workspace folder).
src/components/event-log-workspace/ChannelPicker.tsx Removes old channel picker (moved to workspace folder).
src-tauri/src/menu.rs Adds File menu entries for session save/open + emits corresponding menu actions.
src-tauri/src/lib.rs Registers new commands (file hash, Graph API); gates sysmon module on feature.
src-tauri/src/commands/mod.rs Adds Graph API command module (Windows-only) and gates sysmon commands on feature.
src-tauri/src/commands/file_ops.rs Adds compute_file_hash command (SHA-256 + size).
src-tauri/src/commands/intune.rs Adds Graph API prefetch/enrichment path + policy metadata key normalization.
src-tauri/src/commands/graph_api.rs Adds Tauri command wrappers for Graph API auth/resolve/fetch.
src-tauri/src/intune/guid_registry.rs Adds GraphApi source + insert/unresolved helpers.
src-tauri/src/intune/event_tracker.rs Tweaks appworkload event detail + adds PolicyId GUID extraction path + context scan fix.
src-tauri/src/intune/timeline.rs Updates tests for new IntuneEvent fields.
src-tauri/src/event_log/models.rs Adds error_messages to EVTX parse result model.
src-tauri/src/event_log/parser.rs Initializes error_messages in parse result.
src-tauri/src/event_log/commands.rs Adds per-channel progress emits and error message collection; includes channels with 0 events on errors.
src-tauri/Cargo.toml Adds sysmon feature + sha2 dependency; adjusts feature wiring.
src-tauri/Cargo.lock Adds sha2 dependency entry.
scripts/Launch-CMTraceOpen.sh Fixes script root derivation for environments without BASH_SOURCE.
docs/superpowers/specs/2026-04-02-unified-timeline-design.md Adds design spec for unified timeline merge/correlation.
docs/superpowers/specs/2026-04-02-session-save-restore-design.md Adds design spec for session save/restore.
docs/superpowers/specs/2026-04-02-log-diff-design.md Adds design spec for log diff.
CHANGELOG.md Updates unreleased notes (currently very broad scope under PR #82).
.gitignore Ignores brainstorming + Claude local settings artifacts.
.github/workflows/cmtrace-ci.yml Adds explicit workflow permissions.
.claude/settings.local.json Removes committed Claude local settings file.
Comments suppressed due to low confidence (1)

src/workspaces/event-log/EvtxTimeline.tsx:208

  • The focusable listbox explicitly sets outline: "none", which removes the visible focus indicator for keyboard users. Keep the default outline, or replace it with an accessible custom focus style (e.g., using :focus-visible styling) so focus remains apparent when navigating with arrow keys.

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

Comment thread src/workspaces/event-log/index.ts Outdated
Comment on lines +14 to +18
sidebar: lazy(() =>
import("../dsregcmd/DsregcmdSidebar").then((m) => ({
default: m.DsregcmdSidebar,
}))
),

Copilot AI Apr 5, 2026

Copy link

Choose a reason for hiding this comment

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

The Event Log workspace is wired to lazily load the dsregcmd sidebar, which looks like an accidental copy/paste and will render the wrong sidebar UI when activeView === "event-log". Replace this with an Event Log-specific sidebar component (if needed), or omit sidebar so FileSidebar falls back appropriately.

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +29
fileFilters: [
{ name: "Log Files", extensions: ["log"] },
{ name: "Old Log Files", extensions: ["lo_"] },
{ name: "Registry Files", extensions: ["reg"] },
{ name: "All Files", extensions: ["*"] },
],
actionLabels: {
file: "Open File",
folder: "Open Folder",
placeholder: "Open...",
},

Copilot AI Apr 5, 2026

Copy link

Choose a reason for hiding this comment

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

fileFilters/actionLabels for the Event Log workspace are set up for .log/.reg files, but this workspace’s SourcePicker and backend commands are EVTX-focused. This will cause the global Open dialog to show incorrect filters/labels when the Event Log workspace is active. Align these with EVTX (e.g., .evtx) and appropriate button text.

Copilot uses AI. Check for mistakes.
Comment on lines +22 to +43
fileFilters: [
{ name: "Log Files", extensions: ["log"] },
{ name: "Old Log Files", extensions: ["lo_"] },
{ name: "Registry Files", extensions: ["reg"] },
{ name: "All Files", extensions: ["*"] },
],
actionLabels: {
file: "Open File",
folder: "Open Folder",
placeholder: "Open...",
},
onOpenSource: async (source, _trigger) => {
const folderPath =
source.kind === "folder"
? source.path
: source.kind === "known"
? source.defaultPath
: null;
if (folderPath) {
const { useDeploymentStore } = await import("./deployment-store");
await useDeploymentStore.getState().analyzeFolder(folderPath);
}

Copilot AI Apr 5, 2026

Copy link

Choose a reason for hiding this comment

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

onOpenSource ignores source.kind === "file", but this workspace advertises file filters and an "Open File" action label. That yields a no-op when a user opens a file. Either handle file sources (e.g., analyze the file’s parent folder / treat a file as a single-file folder analysis) or remove the file open affordance for this workspace.

Copilot uses AI. Check for mistakes.
Comment thread src/types/event-log.ts Outdated
Comment on lines 1 to 2
import type { IntuneTimestampBounds } from "../workspaces/intune/types";

Copilot AI Apr 5, 2026

Copy link

Choose a reason for hiding this comment

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

src/types/event-log.ts now type-imports IntuneTimestampBounds from src/workspaces/intune/types, while src/workspaces/intune/types also imports EventLogAnalysis from src/types/event-log. This creates a circular type dependency and couples shared event-log types to a workspace module. Consider moving IntuneTimestampBounds (or a generic TimestampBounds type) into a shared src/types/* module and have both sides import from there.

Copilot uses AI. Check for mistakes.
Comment on lines +30 to +34
function tryStart() {
const { graphApiEnabled, currentPlatform } = useUiStore.getState();
if (!graphApiEnabled || currentPlatform !== "windows") return;
connectAndPopulate();
}

Copilot AI Apr 5, 2026

Copy link

Choose a reason for hiding this comment

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

This startup module may run before the platform-detection effect in Toolbar updates currentPlatform (ui-store defaults currentPlatform to "windows"). If a user has graphApiEnabled persisted as true on a non-Windows platform, this can still attempt Graph API commands and immediately error. Consider deriving the platform directly here (via Tauri platform()), or initializing currentPlatform deterministically before hydration-dependent startup logic runs.

Copilot uses AI. Check for mistakes.
Comment on lines +353 to +359
// Listen for progress events from the Rust backend
listen<{ channel: string; fetched: number }>("evtx-query-progress", (event) => {
useEvtxStore.setState({
loadingChannel: event.payload.channel,
loadingProgress: event.payload.fetched,
});
});

Copilot AI Apr 5, 2026

Copy link

Choose a reason for hiding this comment

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

This store sets up a Tauri event listener at module scope without retaining and disposing the unlisten function. In dev/HMR this can register multiple listeners, and in general it makes lifecycle management harder. Prefer setting up the listener inside a hook/effect with cleanup (as done elsewhere), or store the unlisten promise and expose a teardown/init function to call from a single top-level component.

Copilot uses AI. Check for mistakes.
Comment on lines +132 to +139
// Query all core channels in parallel (bypass queryChannels to avoid isLoading conflicts)
const mergeResult = (ch: string, result: EvtxParseResult) => {
console.log(`[evtx] ${ch}: got ${result.records.length} records, ${result.parseErrors} errors`, result.errorMessages);
const state = get();
const merged = [...state.records, ...result.records];
merged.sort((a, b) => a.timestampEpoch - b.timestampEpoch);
for (let i = 0; i < merged.length; i++) merged[i].id = i;

Copilot AI Apr 5, 2026

Copy link

Choose a reason for hiding this comment

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

console.log in mergeResult will spam the console during live channel loading (especially when loading multiple core channels in parallel). Consider removing this or gating it behind a debug flag so normal users don’t get noisy logs.

Copilot uses AI. Check for mistakes.
Comment thread CHANGELOG.md Outdated
Comment on lines +5 to +24
## [Unreleased] — PR #82

### Added

- **Settings dialog** (replaces Accessibility dialog): Full settings UI with tabs for Appearance (themes, font size), Columns (visibility, ordering), Behavior (confirm tab close), Updates (auto-update toggle), and File Associations (Windows-only). Accessible via `Ctrl+,` or Window menu.
- **Context menu**: Right-click any log row for Copy Line, Copy Message, Jump to Line, Quick Filter by severity/component, Reveal in File Manager, and Error Lookup. Uses native Tauri menu popup for OS-native feel.
- **Event Log workspace** (Windows, feature-gated): Parse `.evtx` files and query live Windows Event Log channels. Supports file-based EVTX parsing with channel grouping, severity filtering, and correlation linking. Frontend workspace with channel sidebar, severity badges, and detail pane.
- **Event Log workspace** (Windows, feature-gated): Parse `.evtx` files and query live Windows Event Log channels. Supports file-based EVTX parsing with channel grouping, severity filtering, and correlation linking. Frontend workspace with channel sidebar, severity badges, and detail pane. Live queries use Win32 Event Log API (`EvtQuery`, `EvtRender`, `EvtFormatMessage`). "This Computer" auto-loads Application, System, Security, and Setup channels in parallel with progressive UI updates. Event Viewer-style nested tree sidebar (split on `-` and `/`) with resizable drag handle. Arrow key navigation, resizable detail pane, per-channel load/refresh buttons, and loading spinner with elapsed time in the status bar.
- **AppWorkload enrichment**: Parse "Get policies" JSON payloads in the log viewer to build GUID-to-app-name mappings. InfoPane shows resolved app names when log messages contain GUIDs, structured policy metadata cards, and decoded base64 PowerShell detection scripts via a lightweight syntax-highlighted code viewer.
- **Activity view**: New "Activity" toggle in the Intune timeline tab groups events by app into collapsible cards. Each card shows worst status, event count, duration, and event type badges. Expanded rows display parsed structured fields (intent, detection, applicability, reboot, GRS expired, enforcement) as colored tags with inline GUID resolution and word-wrapped detail messages.
- **GUID Registry dialog**: New Tools menu item showing a searchable table of all GUID-to-app-name mappings from the Intune analysis, with source confidence ranking (ApplicationName > Name > SetUpFilePath) and click-to-copy.
- **GUID Registry dialog**: New Tools menu item showing a searchable table of all GUID-to-app-name mappings from the Intune analysis, with source confidence ranking (GraphApi > ApplicationName > Name > SetUpFilePath) and click-to-copy.
- **Microsoft Graph API integration** (Windows, opt-in): Resolve Intune app GUIDs to display names via Microsoft Graph API. Authenticates silently using WAM (Web Account Manager) with the device's existing Entra ID session — no app registration required. Gated behind Settings > Graph API toggle (off by default) with consent warnings. Pre-populate cache fetches all apps, remediation scripts, platform scripts, and shell scripts in one call. GUID Registry dialog shows entries in tabbed view (All/Apps/Scripts/Remediations) with publisher and category columns. Auto-connects on startup when enabled, with status indicator in the status bar.
- **SideCarScriptDetectionManager events**: Extract PowerShell script detection lifecycle events (start, complete, exit code, process ID) as standalone PowerShellScript events in the Intune timeline.
- **Resizable InfoPane**: Drag handle between the log list and detail pane allows resizing (min 80px, max 70% viewport).
- **Jump to Line**: Context menu action to jump to a specific line number in the log.
- **Reveal in File Manager**: Context menu action to open the source file's location in Finder/Explorer.
- **Quick Filter**: Context menu action to instantly filter by the selected row's severity or component.
- **Multi-file unified timeline** (PR #81): Merge entries from multiple open log files into a single time-sorted view. Two entry points: "Merge Tabs..." button in the toolbar and "Merge into Timeline" button in the folder sidebar. Color-coded left borders distinguish source files. A legend bar provides per-file toggle visibility, correlation time window, and auto-correlate controls. Cross-file timestamp correlation highlights entries from other files within a configurable time window and shows them in the InfoPane with delta timestamps.
- **Session save/restore**: Save the current workspace state (open files, scroll positions, filters, merged tabs, workspace context) to a `.cmtrace` JSON file via File > Save Session (Ctrl+Shift+S). Restore via File > Open Session or Recent Sessions submenu. Files are integrity-checked with SHA-256 hashes — warns if files have changed or are missing since the session was saved. New `compute_file_hash` Rust backend command.
- **Log diff**: Compare two open log files side-by-side or in unified inline view. Fuzzy pattern matching normalizes GUIDs, timestamps, and long numbers so "same event, different instance" lines are recognized as matches. Stats bar shows common patterns vs. lines unique to each file. "Diff Tabs..." button in the toolbar opens a config dialog for source selection.
- **Sysmon EVTX workspace** (PR #72): Full Sysmon analysis workspace for Windows `.evtx` event log files.

Copilot AI Apr 5, 2026

Copy link

Choose a reason for hiding this comment

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

The changelog entry claims a very broad set of features/PRs under “PR #82” (Graph API, unified timeline, session save/restore, log diff, sysmon, etc.). If this pull request is intended to be only the workspace registry refactor, the changelog looks out of scope/misleading; if the PR really includes these features, the PR title/description should be updated to reflect that scope so reviewers understand the risk/impact.

Copilot uses AI. Check for mistakes.
adamgell and others added 2 commits April 6, 2026 09:36
- event-log: remove incorrect DsregcmdSidebar, fix file filters to EVTX
- deployment: handle file sources by analyzing parent directory
- types: move IntuneTimestampBounds to shared types to break circular dep

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Resolve conflicts between workspace registry refactor and main's
v1.1.0 features (Graph API, session save/restore, event log viewer).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@adamgell
adamgell merged commit ccd10e3 into main Apr 6, 2026
9 checks passed
@adamgell
adamgell deleted the refactor/workspace-registry branch July 30, 2026 00:23
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.

2 participants