# michael-dahlke/cyber-news-tool architecture

> Architecture diagram of the GitHub repository michael-dahlke/cyber-news-tool, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-13). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/michael-dahlke/cyber-news-tool
- Repository: https://github.com/michael-dahlke/cyber-news-tool

## Overview

Cyber News Tool is a macOS cybersecurity-news research app. Users browse categorized and MSRC feeds, open extracted articles, search the archive, and optionally generate KQL from article content; source management and settings configure those workflows. React views call Rust commands through Tauri, with Rust services handling feed ingestion, extraction, search, caching, and KQL, backed by SQLite and OS keychain storage. README documents the major capabilities, while several core handlers and UI modules were not excerpted, so links that depend on their internal call paths are omitted.

Main entry points: [`src/App.tsx`](https://github.com/michael-dahlke/cyber-news-tool/blob/main/src/App.tsx) (App routes), [`src/services/articleService.ts`](https://github.com/michael-dahlke/cyber-news-tool/blob/main/src/services/articleService.ts) (Article IPC client), [`src/services/feedService.ts`](https://github.com/michael-dahlke/cyber-news-tool/blob/main/src/services/feedService.ts) (Feed IPC client), [`src-tauri/src/db/mod.rs`](https://github.com/michael-dahlke/cyber-news-tool/blob/main/src-tauri/src/db/mod.rs) (SQLite archive)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_ui["Desktop interface"]
  node_app["App routes<br/>[App.tsx]"]
  node_settingsui["Settings<br/>[SettingsView.tsx]"]
end

subgraph group_content["News and reading"]
  node_dashboard["News dashboard<br/>[DashboardView.tsx]"]
  node_msrc["MSRC advisories<br/>[MSRCView.tsx]"]
  node_sourceui["Source browser<br/>[SourcesView.tsx]"]
  node_sourcemgr["Source manager<br/>[SourceManager.tsx]"]
  node_reader["Article reader<br/>[ReaderView.tsx]"]
  node_webview["WebView fallback"]
end

subgraph group_backend["Rust application services"]
  node_articleapi["Article IPC client<br/>[articleService.ts]"]
  node_feedapi["Feed IPC client<br/>[feedService.ts]"]
  node_articlecmd["Article commands<br/>[articles.rs]"]
  node_feedcmd["Feed commands<br/>[feeds.rs]"]
  node_feedlogic["Feed processing<br/>[feed_service.rs]"]
  node_extract["Content extraction"]
  node_settingscmd["Settings commands<br/>[settings.rs]"]
end

subgraph group_state["Persistence and secrets"]
  node_keychain["OS keychain<br/>[keychain.rs]"]
  node_db[("SQLite archive<br/>[mod.rs]")]
end

subgraph group_intelligence["Search and KQL"]
  node_searchui["Search results<br/>[SearchResults.tsx]"]
  node_searchapi["Search IPC client<br/>[searchService.ts]"]
  node_searchcmd["Search commands<br/>[search.rs]"]
  node_searchlogic["Full-text search<br/>[search_service.rs]"]
  node_kqlui["KQL generator<br/>[KQLPanel.tsx]"]
  node_kqllogic["KQL generation<br/>[kql_service.rs]"]
end

node_user(("Researcher"))

node_user -->|"opens"| node_app
node_app -->|"routes to"| node_dashboard
node_app -->|"routes to"| node_msrc
node_app -->|"routes to"| node_reader
node_app -->|"routes to"| node_searchui
node_app -->|"routes to"| node_settingsui
node_app -->|"routes to"| node_sourceui
node_user -->|"manages feeds"| node_sourcemgr
node_dashboard -->|"refreshes feeds"| node_feedapi
node_dashboard -->|"loads articles"| node_articleapi
node_msrc -->|"loads advisories"| node_articleapi
node_sourcemgr -->|"manages sources"| node_feedapi
node_sourceui -->|"lists sources"| node_feedapi
node_reader -->|"loads content"| node_articleapi
node_reader -->|"renders fallback"| node_webview
node_feedapi -->|"invokes"| node_feedcmd
node_articleapi -->|"invokes"| node_articlecmd
node_searchui -->|"submits query"| node_searchapi
node_searchapi -->|"invokes"| node_searchcmd
node_searchcmd -->|"executes search"| node_searchlogic
node_searchlogic -->|"queries FTS5"| node_db
node_kqlui -.->|"requests generation"| node_kqllogic
node_settingsui -.->|"configures settings"| node_settingscmd
node_feedcmd -.->|"dispatches feed work"| node_feedlogic
node_feedlogic -.->|"stores articles"| node_db
node_articlecmd -.->|"extracts content"| node_extract
node_articlecmd -.->|"reads article data"| node_db
node_kqllogic -.->|"reads API secret"| node_keychain
node_kqllogic -.->|"stores suggestions"| node_db

click node_app "https://github.com/michael-dahlke/cyber-news-tool/blob/main/src/App.tsx"
click node_dashboard "https://github.com/michael-dahlke/cyber-news-tool/blob/main/src/components/Dashboard/DashboardView.tsx"
click node_msrc "https://github.com/michael-dahlke/cyber-news-tool/blob/main/src/components/Dashboard/MSRCView.tsx"
click node_sourceui "https://github.com/michael-dahlke/cyber-news-tool/blob/main/src/components/Sources/SourcesView.tsx"
click node_sourcemgr "https://github.com/michael-dahlke/cyber-news-tool/blob/main/src/components/Settings/SourceManager.tsx"
click node_reader "https://github.com/michael-dahlke/cyber-news-tool/blob/main/src/components/Reader/ReaderView.tsx"
click node_webview "https://github.com/michael-dahlke/cyber-news-tool/blob/main/src/components/Reader/WebViewFallback.tsx"
click node_articleapi "https://github.com/michael-dahlke/cyber-news-tool/blob/main/src/services/articleService.ts"
click node_feedapi "https://github.com/michael-dahlke/cyber-news-tool/blob/main/src/services/feedService.ts"
click node_articlecmd "https://github.com/michael-dahlke/cyber-news-tool/blob/main/src-tauri/src/commands/articles.rs"
click node_feedcmd "https://github.com/michael-dahlke/cyber-news-tool/blob/main/src-tauri/src/commands/feeds.rs"
click node_feedlogic "https://github.com/michael-dahlke/cyber-news-tool/blob/main/src-tauri/src/services/feed_service.rs"
click node_extract "https://github.com/michael-dahlke/cyber-news-tool/blob/main/src-tauri/src/services/content_extractor.rs"
click node_searchui "https://github.com/michael-dahlke/cyber-news-tool/blob/main/src/components/Search/SearchResults.tsx"
click node_searchapi "https://github.com/michael-dahlke/cyber-news-tool/blob/main/src/services/searchService.ts"
click node_searchcmd "https://github.com/michael-dahlke/cyber-news-tool/blob/main/src-tauri/src/commands/search.rs"
click node_searchlogic "https://github.com/michael-dahlke/cyber-news-tool/blob/main/src-tauri/src/services/search_service.rs"
click node_kqlui "https://github.com/michael-dahlke/cyber-news-tool/blob/main/src/components/KQL/KQLPanel.tsx"
click node_kqllogic "https://github.com/michael-dahlke/cyber-news-tool/blob/main/src-tauri/src/services/kql_service.rs"
click node_settingsui "https://github.com/michael-dahlke/cyber-news-tool/blob/main/src/components/Settings/SettingsView.tsx"
click node_settingscmd "https://github.com/michael-dahlke/cyber-news-tool/blob/main/src-tauri/src/commands/settings.rs"
click node_keychain "https://github.com/michael-dahlke/cyber-news-tool/blob/main/src-tauri/src/services/keychain.rs"
click node_db "https://github.com/michael-dahlke/cyber-news-tool/blob/main/src-tauri/src/db/mod.rs"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_app,node_settingsui toneBlue
class node_dashboard,node_msrc,node_sourceui,node_sourcemgr,node_reader,node_webview toneAmber
class node_articleapi,node_feedapi,node_articlecmd,node_feedcmd,node_feedlogic,node_extract,node_settingscmd toneMint
class node_keychain,node_db toneRose
class node_searchui,node_searchapi,node_searchcmd,node_searchlogic,node_kqlui,node_kqllogic,node_user toneIndigo
```

## Components

### Desktop interface

- [App routes](https://github.com/michael-dahlke/cyber-news-tool/blob/main/src/App.tsx): `src/App.tsx`
- [Settings](https://github.com/michael-dahlke/cyber-news-tool/blob/main/src/components/Settings/SettingsView.tsx): `src/components/Settings/SettingsView.tsx`

### News and reading

- [News dashboard](https://github.com/michael-dahlke/cyber-news-tool/blob/main/src/components/Dashboard/DashboardView.tsx): `src/components/Dashboard/DashboardView.tsx`
- [MSRC advisories](https://github.com/michael-dahlke/cyber-news-tool/blob/main/src/components/Dashboard/MSRCView.tsx): `src/components/Dashboard/MSRCView.tsx`
- [Source browser](https://github.com/michael-dahlke/cyber-news-tool/blob/main/src/components/Sources/SourcesView.tsx): `src/components/Sources/SourcesView.tsx`
- [Source manager](https://github.com/michael-dahlke/cyber-news-tool/blob/main/src/components/Settings/SourceManager.tsx): `src/components/Settings/SourceManager.tsx`
- [Article reader](https://github.com/michael-dahlke/cyber-news-tool/blob/main/src/components/Reader/ReaderView.tsx): `src/components/Reader/ReaderView.tsx`
- [WebView fallback](https://github.com/michael-dahlke/cyber-news-tool/blob/main/src/components/Reader/WebViewFallback.tsx): `src/components/Reader/WebViewFallback.tsx`

### Rust application services

- [Article IPC client](https://github.com/michael-dahlke/cyber-news-tool/blob/main/src/services/articleService.ts): `src/services/articleService.ts`
- [Feed IPC client](https://github.com/michael-dahlke/cyber-news-tool/blob/main/src/services/feedService.ts): `src/services/feedService.ts`
- [Article commands](https://github.com/michael-dahlke/cyber-news-tool/blob/main/src-tauri/src/commands/articles.rs): `src-tauri/src/commands/articles.rs`
- [Feed commands](https://github.com/michael-dahlke/cyber-news-tool/blob/main/src-tauri/src/commands/feeds.rs): `src-tauri/src/commands/feeds.rs`
- [Feed processing](https://github.com/michael-dahlke/cyber-news-tool/blob/main/src-tauri/src/services/feed_service.rs): `src-tauri/src/services/feed_service.rs`
- [Content extraction](https://github.com/michael-dahlke/cyber-news-tool/blob/main/src-tauri/src/services/content_extractor.rs): `src-tauri/src/services/content_extractor.rs`
- [Settings commands](https://github.com/michael-dahlke/cyber-news-tool/blob/main/src-tauri/src/commands/settings.rs): `src-tauri/src/commands/settings.rs`

### Persistence and secrets

- [OS keychain](https://github.com/michael-dahlke/cyber-news-tool/blob/main/src-tauri/src/services/keychain.rs): `src-tauri/src/services/keychain.rs`
- [SQLite archive](https://github.com/michael-dahlke/cyber-news-tool/blob/main/src-tauri/src/db/mod.rs): `src-tauri/src/db/mod.rs`

### Search and KQL

- [Search results](https://github.com/michael-dahlke/cyber-news-tool/blob/main/src/components/Search/SearchResults.tsx): `src/components/Search/SearchResults.tsx`
- [Search IPC client](https://github.com/michael-dahlke/cyber-news-tool/blob/main/src/services/searchService.ts): `src/services/searchService.ts`
- [Search commands](https://github.com/michael-dahlke/cyber-news-tool/blob/main/src-tauri/src/commands/search.rs): `src-tauri/src/commands/search.rs`
- [Full-text search](https://github.com/michael-dahlke/cyber-news-tool/blob/main/src-tauri/src/services/search_service.rs): `src-tauri/src/services/search_service.rs`
- [KQL generator](https://github.com/michael-dahlke/cyber-news-tool/blob/main/src/components/KQL/KQLPanel.tsx): `src/components/KQL/KQLPanel.tsx`
- [KQL generation](https://github.com/michael-dahlke/cyber-news-tool/blob/main/src-tauri/src/services/kql_service.rs): `src-tauri/src/services/kql_service.rs`

### Other components

- **Researcher**

## Connections

- Researcher → App routes: opens (evidence: `README.md`)
- App routes → News dashboard: routes to (evidence: `src/App.tsx`)
- App routes → MSRC advisories: routes to (evidence: `src/App.tsx`)
- App routes → Article reader: routes to (evidence: `src/App.tsx`)
- App routes → Search results: routes to (evidence: `src/App.tsx`)
- App routes → Settings: routes to (evidence: `src/App.tsx`)
- App routes → Source browser: routes to (evidence: `src/App.tsx`)
- Researcher → Source manager: manages feeds (evidence: `README.md`)
- News dashboard → Feed IPC client: refreshes feeds (evidence: `src/components/Dashboard/DashboardView.tsx`)
- News dashboard → Article IPC client: loads articles (evidence: `src/components/Dashboard/DashboardView.tsx`)
- MSRC advisories → Article IPC client: loads advisories (evidence: `src/components/Dashboard/MSRCView.tsx`)
- Source manager → Feed IPC client: manages sources (evidence: `src/components/Settings/SourceManager.tsx`)
- Source browser → Feed IPC client: lists sources (evidence: `src/components/Sources/SourcesView.tsx`)
- Article reader → Article IPC client: loads content (evidence: `src/components/Reader/ReaderView.tsx`)
- Article reader → WebView fallback: renders fallback (evidence: `src/components/Reader/ReaderView.tsx`)
- Feed IPC client → Feed commands: invokes (evidence: `src/services/feedService.ts`)
- Article IPC client → Article commands: invokes (evidence: `src/services/articleService.ts`)
- Search results → Search IPC client: submits query (evidence: `src/components/Search/SearchResults.tsx`)
- Search IPC client → Search commands: invokes (evidence: `src/services/searchService.ts`)
- Search commands → Full-text search: executes search (evidence: `src-tauri/src/commands/search.rs`)
- Full-text search → SQLite archive: queries FTS5 (evidence: `src-tauri/src/services/search_service.rs`)
- KQL generator → KQL generation: requests generation
- Settings → Settings commands: configures settings
- Feed commands → Feed processing: dispatches feed work
- Feed processing → SQLite archive: stores articles (evidence: `src-tauri/src/services/feed_service.rs`)
- Article commands → Content extraction: extracts content
- Article commands → SQLite archive: reads article data
- KQL generation → OS keychain: reads API secret (evidence: `src-tauri/src/services/kql_service.rs`)
- KQL generation → SQLite archive: stores suggestions (evidence: `src-tauri/src/services/kql_service.rs`)
