From d8862a9b78b0d6cf4e11cf537be7678794e08811 Mon Sep 17 00:00:00 2001 From: Christian Cleberg Date: Fri, 17 Jul 2026 16:06:47 -0500 Subject: Scaffold octosentry MVP: unified GitHub security alert feed MenuBarExtra popover aggregating Dependabot, code scanning, and secret scanning alerts for a single repo into one severity-ranked stream. Swift 6 strict concurrency, zero third-party dependencies, PAT-via-env-var auth as a dev-only shortcut ahead of the device authorization flow. --- octosentry/GitHubAPIModels.swift | 88 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 octosentry/GitHubAPIModels.swift (limited to 'octosentry/GitHubAPIModels.swift') diff --git a/octosentry/GitHubAPIModels.swift b/octosentry/GitHubAPIModels.swift new file mode 100644 index 0000000..3a84aa8 --- /dev/null +++ b/octosentry/GitHubAPIModels.swift @@ -0,0 +1,88 @@ +// +// GitHubAPIModels.swift +// octosentry +// +// Decodable wire types for the three GitHub REST alert endpoints. Kept +// private to this file — GitHubSecurityAPIClient maps them into SecurityEvent. +// + +import Foundation + +nonisolated struct DependabotAlertDTO: Decodable { + let number: Int + let htmlUrl: URL + let createdAt: Date + let updatedAt: Date + let securityAdvisory: SecurityAdvisory + + struct SecurityAdvisory: Decodable { + let summary: String + let severity: String + } + + enum CodingKeys: String, CodingKey { + case number + case htmlUrl = "html_url" + case createdAt = "created_at" + case updatedAt = "updated_at" + case securityAdvisory = "security_advisory" + } +} + +nonisolated struct CodeScanningAlertDTO: Decodable { + let number: Int + let htmlUrl: URL + let createdAt: Date + let updatedAt: Date + let rule: Rule + let mostRecentInstance: MostRecentInstance? + + struct Rule: Decodable { + let id: String? + let description: String? + let severity: String? + let securitySeverityLevel: String? + + enum CodingKeys: String, CodingKey { + case id + case description + case severity + case securitySeverityLevel = "security_severity_level" + } + } + + struct MostRecentInstance: Decodable { + let message: Message? + + struct Message: Decodable { + let text: String? + } + } + + enum CodingKeys: String, CodingKey { + case number + case htmlUrl = "html_url" + case createdAt = "created_at" + case updatedAt = "updated_at" + case rule + case mostRecentInstance = "most_recent_instance" + } +} + +nonisolated struct SecretScanningAlertDTO: Decodable { + let number: Int + let htmlUrl: URL + let createdAt: Date + let updatedAt: Date + let secretTypeDisplayName: String + let validity: String? + + enum CodingKeys: String, CodingKey { + case number + case htmlUrl = "html_url" + case createdAt = "created_at" + case updatedAt = "updated_at" + case secretTypeDisplayName = "secret_type_display_name" + case validity + } +} -- cgit v1.2.3