summaryrefslogtreecommitdiff
path: root/DomainDig.xcodeproj
Commit message (Collapse)AuthorAgeFilesLines
* feat: versioned store-migration policy for persisted data (v5 step 2)Christian Cleberg11 days1-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Third v5.0.0 roadmap item: define and implement a migration policy for the on-device persisted store (tracked domains, history/snapshots, audits, workflows, monitoring, settings), so data upgrades cleanly across app versions instead of relying on a one-shot marker. - DataMigrationService is reworked from a single boolean marker (`data.migrations.v3_4_0`) into a versioned runner keyed by an integer store schema version (`data.storeSchemaVersion`). It runs each step once in ascending order up to `currentStoreSchemaVersion`, stamping the version as it goes. Adding a future migration is now a `case N:` plus a version bump. Policy guarantees, all covered by tests: - Forward-only and idempotent; every step must be safe on an empty/older store. - Never downgrades: a store written by a newer build (higher version) is left byte-for-byte untouched. - Pre-versioning installs are handled: a set legacy boolean marker reads as "already at v1", so the v1 normalization never re-runs for them. v1 is the existing normalization pass (dedup + drop the legacy `watchedDomains` key + sanitize monitoring settings), now expressed as migration step 1. - Docs/data-migration.md documents the persisted surface, the two independent version lines (store vs. backup export), when to use lenient decoding vs. a migration step, the runner contract, an "adding a migration" checklist, and backup-import compatibility. Linked from the README. - DataMigrationServiceTests: 6 tests over legacy fixtures — fresh-store stamping, legacy `watchedDomains` migration + key drop, in-place dedup of the stored blob, idempotence, legacy-marker-as-v1, and the no-downgrade guard. Full unit suite: 58 passing.
* feat: stabilize and document the Local API v1 response contract (v5 step 3)Christian Cleberg11 days1-0/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | Second v5.0.0 roadmap item: make the Local API's public JSON contract explicit, documented, and regression-locked, so external consumers (Shortcuts, scripts, integrations) have a stable surface with a defined compatibility promise. - LocalAPIContract: new single source of truth for the wire-format version ("v1") and the canonical JSON encoder (ISO-8601 dates, sorted keys). Both the success and error paths in LocalAPIService now route through it, so the format can't drift between them, and the ad-hoc per-call-site encoders are gone. - The response envelope and every payload struct are promoted from `private` to internal so the contract is a first-class, testable part of the module. The transport/handler internals (request parser, HTTP response, secret store) stay private. - Docs/local-api.md documents the base URL/auth, the envelope, the encoding conventions (notably: absent optionals are omitted, not null), every endpoint and its payload fields, the error codes, and the semantic-version-style compatibility policy (additive changes keep v1; renames/removals/type changes bump the version). Linked from the README. - LocalAPIContractTests: 16 structure/"golden" tests pinning the envelope shape, each payload's field names, the enum encodings, and the ISO-8601 date format. They assert structure, not values, so ordinary behavior changes don't churn them but a renamed or dropped field fails CI. Full unit suite: 52 passing.
* test: establish unit-test net for the deterministic core (v5 step 1)Christian Cleberg11 days2-8/+181
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Stands up the DomainDigTests unit-test target the v5.0.0 roadmap flags as the mandatory first move before decomposing the god-files and locking external contracts. The project had no XCTest unit target — only the DomainDigUITests accessibility suite. - New DomainDigTests target (unit_test_bundle), hosted by the app so @testable import DomainDig links. Mirrors the UITests build settings (SWIFT_VERSION 5.0 + MainActor default isolation) to avoid the XCTest override-isolation issue recorded for the Swift 6 targets. Wired into the shared DomainDig scheme's Test action, so it runs in CI and the pre-push audit hook automatically (both invoke the whole scheme). - SnapshotFixture builds the deep LookupSnapshot/DomainReport models through their real initializer and the DomainReportBuilder, exposing only the fields the tests vary. - 36 characterization tests across the four deterministic units the roadmap names: - DiffService: change classification, case/whitespace normalization, DNS record reorder-vs-change, summary phrasing, resolver context note, certificate-warning thresholds. - DomainReportBuilder: snapshot -> report field mapping, primary-IP and DNSSEC derivation, TLS status, partial-snapshot/validation passthrough. - DomainReportExporter: format dispatch, JSON round-trip (the machine contract), CSV/markdown/text/PDF structural invariants, timeline. - DomainDataPortabilityService: CSV round-trip and the merge/dedup semantics (case-insensitive collapse, OR-merged pin state, min-created/max-updated, recency sort) via an ephemeral UserDefaults suite. - build.yml comment updated to reflect the second test target.
* chore: bump to v4.9.0; record the release in the roadmapv4.9.0Christian Cleberg12 days1-16/+16
| | | | | | | | | | | | | | | | | | MARKETING_VERSION 4.8.3 -> 4.9.0 and CURRENT_PROJECT_VERSION 43 -> 44 across all targets, with AppVersion.current aligned — the three-way consistency v4.4.1 established. The roadmap gains the v4.9.0 entry: the full accessibility pass (#21 phases 0-5 — semantic colours, light mode and the appearance setting, Dynamic Type reflow and tap targets, VoiceOver, colour independence and motion/transparency), the audit harness with seeded fixtures and the engaged enforcement ratchet, the manual verification checklist, and Swift 6 language mode adoption (#27). Deferred device passes are named rather than implied. The v5.0.0 "establish a test target" bullet is rewritten to match reality: a UI test target now exists with an enforcement gate; what remains for v5.0.0 is unit coverage of the deterministic core.
* fix: adopt Swift 6 language mode; resolve all concurrency issues (#27)Christian Cleberg13 days1-6/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | All three product targets (app, widget, share extension) now build under SWIFT_VERSION = 6.0 with zero errors and zero warnings. The UITests target stays on 5.0: XCTestCase's nonisolated setUp/init overrides conflict with the target's MainActor default isolation under 6, and test tooling is not shipping code. The original seven diagnostics, plus the layers Swift 6 mode surfaced once those cleared: - SMTPChannel is an actor. It was implicitly MainActor while running its receive loop on a background queue, so parsedLines/lineWaiters/ receiveBuffer were declared main-actor-protected and mutated off it — concurrent mutation while resuming a CheckedContinuation can double-resume, which traps. The actor serialises all state; Network callbacks hop in via Task. The start() continuation also gains an OSAllocatedUnfairLock resume-once guard: the state handler can fire .ready and later .failed, and resuming twice was a pre-existing trap of the same family. - CachedLookupResult is nonisolated (a value pair built inside actor LookupRuntime cannot have a MainActor-bound memberwise init) with conditional Sendable — opting out of MainActor isolation also opted out of the implicit Sendable that globally-isolated types get. - PortScanService.printableBanner is nonisolated: a pure transformation called from the connection's queue. - SweepActivityController stores the activity's Sendable id instead of the non-Sendable Activity, re-resolving via Activity.activities inside each fire-and-forget task, so nothing non-Sendable crosses isolation. - App Intents' static title/description/openAppWhenRun become lets (get-only protocol requirements; static var is shared mutable global state), and the summary helpers are @MainActor to match the model properties they read and the perform() implementations that call them. - ExternalDataService's ISO8601DateFormatter is nonisolated(unsafe), citing Apple's documented thread-safety, rather than risking a parser behaviour change by switching APIs with no test coverage. - TaskMetricsDelegate.metrics is nonisolated(unsafe): written on the session's delegate queue, read only after the request completes, and URLSession guarantees didFinishCollecting precedes task completion. - The share extension extracts the host via async/withCheckedContinuation instead of sending a non-Sendable completion into loadItem's @Sendable handler; Task inherits the view controller's MainActor so the manual DispatchQueue.main hop goes too. Validated: clean Swift 6 build of all product targets, and the full enforced 11-test audit suite green on the floor runtime — Swift 6's runtime isolation checks ran the app through every screen without a trap.
* feat(a11y): add accessibility audit harness (#21 phase 0)Christian Cleberg2026-07-202-2/+130
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Phase 0 of the accessibility pass: a regression guard that must exist before any of the remedial phases, so their acceptance criteria are enforced rather than asserted once by hand. - Fix the project-level IPHONEOS_DEPLOYMENT_TARGET, which was 26.2 while all three targets are 17.6. It was shadowed everywhere today, but any target added later would silently inherit it and drop iOS 17.6 support with no error. - Add a DomainDigUITests target running performAccessibilityAudit on the six primary screens, plus a sweep of every root screen at AccessibilityXXXL. Uses the existing DOMAIN_DIG_FORCE_PRO_PLUS debug argument so Pro-gated screens are reachable. - Findings are reported, not failed. The audit surfaces violations that exist today, so gating on them would block unrelated PRs until the whole pass lands. Enforcement is a committed constant, AccessibilityAuditHarness.enforcedAuditTypes, widened per audit type as each phase clears a category. - CI now runs xcodebuild test across two simulators. Audit coverage is not nested between OS versions: on Tracked Domains, iOS 18.6 reported 2 findings and iOS 27.0 reported 6 (including contrast and element-detection issues 18.6 never raised), while at accessibility text sizes the Dashboard produced a hit-region finding on 18.6 that 27.0 did not. - Simulator selection is now dynamic and floor-aware. The previous selector took the first iPhone from any runtime, which can resolve to a simulator below the deployment target where the app cannot install. Baseline on iOS 18.6: 15 findings across 7 tests — text clipping on every screen, contrast on Inspect and Settings, and a hit-region failure on the Dashboard at accessibility text sizes.
* v4.8.3: Clear SonarCloud new-code issuesChristian Cleberg2026-07-201-12/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Fixes the 4 reported bugs and ~97 code smells flagged in the new-code period. No behavior changes. Bugs (swift:S3923) — DomainInspectionService's confidenceFor* helpers each returned `error == nil ? .low : .low`, an inert conditional. Simplified to `return .low` and dropped the now-unused `error` parameter. Smells: - Merged 14 identical `.empty`/`.error` switch branches in DomainViewModel - Consolidated duplicate implementations (clearPresentedResults/reset, String.nonEmpty/nilIfEmpty, ExportFormat.id/fileExtension) - Extracted nested ternaries into TLSGrade.tone, EmailSecurityGrade.tone, and ChangeImpactClassification.color; removed ContentView.impactColor and the duplicate mapping in BatchResultsView - Documented empty closures and singleton inits - Marked unused protocol-conformance parameters `_` - Renamed CloudSyncTrigger.`import` to `imported` (raw value preserved) and SSLSessionDelegate's _serverTrust/_tlsMetadata - Merged nested ifs in the DER parser; flattened closure nesting in PortScanService and IntegrationService - Replaced two-case switches with if/else Left open: S107 (init parameter counts), S115 (constants mirroring DoH and ipapi JSON keys), S1075 (false positives on https:// literals), and two S117 hits on SwiftUI $binding shorthand. These want a Won't Fix resolution in SonarCloud, not a code change.
* v4.8.2: Bump version and mark shipped in roadmapv4.8.2Christian Cleberg2026-07-201-12/+12
| | | | | | | | Bump AppVersion/marketing version to 4.8.2 and build number to 42 across the app, widget, and share extension targets. Mark v4.8.2 (delivery visibility for disabled integrations, forced queue retries, unreachable-domain reporting, Swift 6 concurrency warnings, synced StoreKit configuration) shipped in RELEASE_ROADMAP.md and record the UAT follow-ups as resolved.
* chore: rename StoreKit configuration to SyncedProducts.storekitChristian Cleberg2026-07-202-3/+3
| | | | | | | | | | | DomainDig.storekit sat beside the DomainDig/ source folder, and Xcode treated the two as conflicting when creating the synced configuration — the resulting confirmation dialog offered to replace the folder. Naming the file SyncedProducts.storekit removes the collision entirely and matches the convention Xcode uses for synced configurations elsewhere. Updates the project file reference and the scheme's StoreKitConfigurationFileReference to match.
* chore: adopt synced StoreKit configurationChristian Cleberg2026-07-201-0/+2
| | | | | | | | | | | | | Xcode synced DomainDig.storekit against App Store Connect, replacing the hand-authored placeholders with real values: the app's internal ID (6760368004), the real subscription group ID (22051301), a synchronized timestamp, and group localizations. Also registers the file in the project so Xcode can find and re-sync it, but without target membership. Xcode's default added it to the Resources build phase of all three targets, which would ship the test configuration inside the app, widget, and share extension bundles. The scheme references it by path for the Run action; it does not need bundling.
* fix: StoreKit config path and Swift 6 concurrency warningsChristian Cleberg2026-07-201-1/+1
| | | | | | | | | | | | | | | | | | The StoreKitConfigurationFileReference added in #11 used one '../' too many, resolving outside the repository. Xcode resolves it relative to the .xcodeproj's xcshareddata directory, so two levels reaches the repo root. SweepActivityAttributes is now explicitly nonisolated. The app target sets SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor while the widget target does not, so a type shared by both inferred a main-actor-isolated ActivityAttributes conformance that ActivityKit cannot use from its concurrent contexts. LocalAPIService's logger closures captured self strongly while their inner Tasks declared [weak self]. The weak capture is now on the outer closure and bound before the Task, so the concurrently-executing closure references an immutable strong local rather than the weak capture.
* test: add StoreKit configuration for local IAP testingChristian Cleberg2026-07-201-1/+4
| | | | | | | | | | | | | | Adds DomainDig.storekit mirroring the App Store Connect setup: one subscription group with Pro+ at level 1 and Pro at level 2, using the corrected product IDs. Wires it into the Run action so purchases resolve locally against StoreKit instead of the App Store, and disables the DOMAIN_DIG_FORCE_PRO_PLUS launch argument, which bypasses StoreKit entirely and would mask whether the purchase path works. Prices in the configuration are local-testing placeholders and do not need to match App Store Connect.
* v4.8.1: Bump version and mark shipped in roadmapChristian Cleberg2026-07-201-12/+12
| | | | | | | | Bump AppVersion/marketing version to 4.8.1 and build number to 41 across the app, widget, and share extension targets. Mark v4.8.1 (scheduled report tap target, completed Pro gate, markdown underline rendering, DNS record dedup, inspect tab keyboard behavior) shipped in RELEASE_ROADMAP.md, and note the three follow-ups filed during UAT.
* fix: Generate Now tap target, remove keyboard dismiss button and launch focusChristian Cleberg2026-07-201-2/+2
| | | | | | | | | | | | | | | | Scheduled Reports: the entire Overview section was wrapped in a single VStack inside one List row, so SwiftUI collapsed every control into one tap target and the menu-style Cadence Picker captured taps intended for the Generate Now button. Unwraps the VStack so each control is its own row, matching the pattern used in IntegrationsView and elsewhere. Also extends the .automatedMonitoring gate to the two Pickers and the Generate Now button. Previously only the Toggle was disabled, leaving a button that appeared active on Free but silently no-opped against the guard in ScheduledReportService. Inspect tab: removes the keyboard toolbar's Dismiss Keyboard button and the onAppear that focused the single-domain field at launch.
* misc. cleanupChristian Cleberg2026-07-201-2/+2
|
* v4.8.0: Bump version and mark shipped in roadmapChristian Cleberg2026-07-201-12/+12
| | | | | | | Bump AppVersion/marketing version to 4.8.0 and build number to 40 across the app, widget, and share extension targets. Mark v4.8.0 (markdown/PDF export, scheduled reports, stronger share affordances, verified local API consistency) shipped in RELEASE_ROADMAP.md.
* v4.7.0: Bump version and mark shipped in roadmapv4.7.0Christian Cleberg2026-07-171-12/+12
| | | | | | | Bump AppVersion/marketing version to 4.7.0 and build number to 39 across the app, widget, and share extension targets. Mark v4.7.0 (comparison, reputation, tags/saved views) shipped in RELEASE_ROADMAP.md and escalate the overdue XCTest-target gap ahead of v5.0.0.
* Xcode: backfill extension display-name build settingsv4.6.0Christian Cleberg2026-07-171-0/+4
|
* Implement v4.6.0: sweep Live Activity, share extension, iPad split view, ↵Christian Cleberg2026-07-172-19/+170
| | | | | | | | | | | | | | | | actionable notifications - Sweep Live Activity: SweepActivityAttributes (Shared/), lock-screen + Dynamic Island UI in the widget extension, driven by SweepActivityController wired into the batch pipeline (begin/update/end); NSSupportsLiveActivities in Info.plist. - Share extension (DomainDigShareExtension): accepts a web URL from the share sheet, extracts the host, and hands it to the app via the App Group inbox (DomainDigShareInbox); the app consumes it on activation and inspects it. - iPad layout: RootTabView uses NavigationSplitView in the regular size class and the tab bar in compact. - Actionable notifications: per-domain threadIdentifier grouping, a Re-inspect action, and tap routing into the domain detail via the intent router. - Bump version to 4.6.0 (build 38) across app, widget, and share targets.
* Complete v4.5.0: Run Sweep intent, detail deep link, and portfolio widgetChristian Cleberg2026-07-172-0/+178
| | | | | | | | | | | | | | | | | Finishes the v4.5.0 "Home Screen & Shortcuts reach" scope that the tag shipped partially: - Add RunSweepIntent (opens the app and runs refreshAllTrackedDomains via the in-process router) and expose it in DomainDigShortcuts. - Extend the domaindig:// scheme with `sweep` and `domain` (detail) actions; route .detail to present TrackedDomainDetailView and .sweep to refresh the watchlist. Move DomainDigDeepLink into Shared/ so the widget can build links. - Add a WidgetKit extension (DomainDigWidgetExtension) with small/medium/large Portfolio widgets showing health counts, per-domain status, and certificate countdowns; tapping a domain deep-links into its detail. - Share portfolio state via an App Group (group.net.cleberg.DomainDig): the app writes a DomainDigWidgetData snapshot on launch/foreground and on watchlist changes and reloads timelines; the widget reads the same store.
* DomainDig v4.5.0: Add App Intents, Shortcuts, and a domaindig:// deep linkChristian Cleberg2026-07-161-4/+4
| | | | | | | | | | | - Add InspectDomainIntent that runs the headless inspection pipeline and returns a summary for Shortcuts, Spotlight, the Action button, and Siri - Add AddToWatchlistIntent that opens the app and tracks a domain through the existing premium-checked path via an in-process router - Register the domaindig:// URL scheme with inspect/watch deep links routed in RootTabView (onOpenURL) - Expose both intents through DomainDigShortcuts (AppShortcutsProvider) - Bump AppVersion/marketing version to 4.5.0 and build number to 37
* DomainDig v4.4.1: Consolidate Audit Mode and remove the CLI targetv4.4.1Christian Cleberg2026-07-162-113/+6
| | | | | | | | | | | - Make DomainDig/DomainDig/Audit* the single active Audit Mode implementation (models, views, exporter) with an Audit tab and session/export UI - Include audit sessions in backup/restore lifecycle counts, summaries, and merge behavior via DomainDataPortabilityService - Remove the DomainDigCLI target, source file, scheme, and all project references; keep the shared inspection/report pipeline for the app - Align AppVersion.current to 4.4.1 and refresh README/architecture docs - Add RELEASE_ROADMAP.md
* DomainDig v3.5.0: Expand the Pro+ Data+ intelligence layer with deeper local ↵Christian Cleberg2026-04-261-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | historical context and inferred enrichment. - add derived intelligence fields for provider fingerprinting, classification, ownership transitions, hosting transitions, subdomain history, risk signals, and inferred timeline events - expand DNS history beyond A/NS snapshots to retain A, AAAA, MX, NS, TXT, and CNAME change state - persist enriched intelligence in snapshots and history entries so analysis is local-first and incremental - add a dedicated Data+ Intelligence panel to current and historical domain detail views - surface intelligence events in timeline rows and include Data+ changes in diff output - preserve non-blocking inspection behavior by keeping enrichment additive to the main lookup path This makes Pro+ materially deeper for investigative workflows by improving historical ownership visibility, infrastructure context, hosting change detection, subdomain intelligence, and explainable risk signals.
* DomainDig v4.2.0: Add a local-only HTTP API layer for DomainDigChristian Cleberg2026-04-261-4/+16
| | | | | | | | | | | | | | | | | | | | Expose DomainDig as a programmable local domain intelligence engine over localhost with explicit user opt-in and token-based authentication. Highlights: - add a localhost-only API server with safe start/stop lifecycle - require a local token for every request and store it in Keychain - add read endpoints for portfolio, domains, history, events, and monitoring - add inspection endpoints that reuse the existing inspection engine - add monitoring enable/disable control endpoints - add structured JSON response envelopes with API versioning - add lightweight capped request logging with clear/reset support - add a Settings UI for Local API enablement, token management, status, and logs - start the server on launch only when enabled - include Local API secrets in local data reset cleanup This is the first programmability release for DomainDig and establishes the foundation for Shortcuts, scripts, and other local automation workflows.
* DomainDig v4.1.0: Add a full local data reset flow in Data ManagementChristian Cleberg2026-04-251-4/+4
| | | | | | | | | | | | | | | | | | | | - add a destructive Delete All Data action with confirmation, progress, success, and failure handling - centralize wipe behavior in DataResetService instead of scattering delete logic in views - clear local persistence, temp/export files, integration secrets, notifications, caches, and in-memory app state - reset sync, purchase, and integration services after wipe so the app returns to a clean first-launch state Polish batch and empty-state UX - present the batch sweep summary after manual bulk searches complete, not only from Watchlist - align the Workflows empty state styling with other empty states by removing the extra background card treatment Bump the project version from 4.0.0 to 4.1.0
* DomainDig v4.0.0 — IntegrationsChristian Cleberg2026-04-251-4/+4
| | | | | | | | | | | | * Outbound webhook delivery * Native Slack webhook integration * SMTP-based email alerts * Per-integration event filtering * Reliable local delivery queue * Delivery logs and retry visibility * Integration management UI * Normalized event severity model * Canonical structured event payloads
* DomainDig v3.9.0 — Portfolio DashboardChristian Cleberg2026-04-252-6/+6
| | | | | | | | | | | * Portfolio summary cards * Recent activity feed across tracked domains * Attention-required queue prioritized by severity * Certificate expiry visibility and expiring-soon section * Quick portfolio filters for triage * Deterministic per-domain health scoring * Local portfolio search * Apex-domain grouping for tracked assets
* DomainDig v3.8.0 — Smart MonitoringChristian Cleberg2026-04-243-4/+97
| | | | | | | | | * Stable domain intervals * Frequent changes decrease intervals * Duplicate states do not trigger alerts * Quiet hours suppress alerts * Quiet hours across midnight work correctly * Sensitivity levels alter behavior as expected
* feat(v3.7.0): add timeline and advanced diffing systemChristian Cleberg2026-04-242-6/+6
| | | | | | | | | | - introduce TimelineView for historical snapshots - allow comparison between any two snapshots - implement DiffService for structured domain diffs - improve diff visualization with clear change indicators - add navigation across changes - optimize history loading for performance - extend CLI and export to support timeline data
* feat(v3.6.0): add iCloud sharing for workflows and tracked domainsChristian Cleberg2026-04-232-6/+13
| | | | | | | | | | | | | | | | - implement CloudKit sharing (CKShare) for TrackedDomain and DomainWorkflow - support read-only and editable permissions - add Share actions and shared state indicators in UI - handle shared record ownership and participant roles - implement deterministic conflict resolution to prevent duplication - ensure compatibility with existing iCloud sync layer - maintain local-first behavior with graceful offline handling - remove debug logging for domain availability/rdap messages notes: - no custom backend or accounts introduced - sharing is Apple ecosystem only (iCloud-based) - large history data remains local-only
* feat(v3.4.0): add backup, restore, and data portabilityChristian Cleberg2026-04-231-4/+12
| | | | | | | | | | | • introduce versioned DomainDig backup format • add full backup export/import with merge and replace modes • implement data validation and conflict handling • add partial exports for tracked domains, workflows, and history • add Data Portability settings section • support Files/iCloud Drive import and export • harden migrations for evolving local models • extend CLI with backup export and validation
* feat(v2.9.0): add risk scoring and deterministic insight engineChristian Cleberg2026-04-221-4/+4
| | | | | | | | | * introduce domain risk assessment with transparent factors * add insight engine for actionable observations * implement cross-domain insights for workflows * improve DNS, subdomain, email, and TLS interpretation * classify change impact severity * include insights and risk in export
* feat(v2.8.0): add workflows and repeatable inspection automationChristian Cleberg2026-04-221-4/+4
| | | | | | | | | | * introduce DomainWorkflow model and persistence * add WorkflowsView and execution flow * support batch inspection via workflows * add workflow-based export (TXT/CSV/JSON) * enable bulk add from history/watchlist * add quick actions for common operations * integrate workflows with tracking and history
* feat(v2.7.0): add provenance, confidence, and reproducibility metadataChristian Cleberg2026-04-221-6/+6
| | | | | | | | | | * add result provenance across major sections * introduce confidence levels for ambiguous outputs * distinguish observed facts from inferred summaries * expand snapshot metadata for reproducibility * improve error classification and partial snapshot handling * include provenance and confidence in export * add local notes for tracked domains and history
* feat(v2​.6​.0): refine ​UI, density, and usabilityChristian Cleberg2026-04-221-4/+4
| | | | | | | | | • add compact/comfortable density modes • implement collapsible sections and sticky summary header • improve visual status indicators and copy actions • refine watchlist and history UX with swipe actions • reorganize settings and improve empty states • add subtle animations and accessibility improvements
* feat(v2.5.0): add caching, request deduplication, and performance improvementsChristian Cleberg2026-04-211-39/+39
|
* feat(v2.4.0): add JSON output, CLI foundation, and shared report layerChristian Cleberg2026-04-212-4/+124
| | | | | | | | | * introduce DomainReport as canonical output model * add JSON export for single and batch results * create DomainReportBuilder for reusable report construction * add CLI target using shared inspection pipeline * refactor services for UI-independent usage * ensure consistency across TXT, CSV, and JSON outputs
* feat(v2.3.0): add ownership intelligence and subdomain discoveryChristian Cleberg2026-04-211-4/+4
| | | | | | | | | * implement RDAP-based ownership section * add ownership diffing and change classification * add passive subdomain discovery via certificate transparency * highlight interesting subdomains * introduce Data+ scaffolding for future features * include ownership and subdomains in export and history
* feat(v2.2.0): add foreground monitoring, notifications, and smarter diffsChristian Cleberg2026-04-211-6/+6
| | | | | | | | | | | - implement “Check All” sweep for tracked domains - add local notifications for changes and certificate expiration - introduce change severity filtering (low/medium/high) - enhance change summaries and diff readability - add certificate expiration tracking and alerts - improve watchlist indicators for changes - add sweep summary screen - optimize performance for larger watchlists
* feat(v2.1.0): add bulk workflows, CSV export, and filteringChristian Cleberg2026-04-201-4/+4
|
* feat(v2.0.0): introduce tracked domains, diffing, and monitoring foundationsv2.0.0Christian Cleberg2026-04-201-4/+4
| | | | | | | | | | | | | | | | | | - replace basic watchlist with structured TrackedDomain model - add manual refresh flow for tracked domains - implement snapshot diffing (DNS, IP, TLS, HTTP, redirect, email, availability) - add change summaries (changed/unchanged + affected sections) - link tracked domains to history snapshots - enhance HistoryEntry with normalized summary fields - persist availability + suggestions in history and export - add WatchlistView with pinning, notes, and status display - introduce premium capability scaffolding (no StoreKit) - enforce free-tier tracked domain limit (local only) - refactor view model to support tracking, diffing, and refresh flows notes: - no background monitoring, notifications, or paid APIs yet - all features remain local-first and manual
* feat(v1.9.0): add domain availability lookup and watchlist foundationChristian Cleberg2026-04-201-4/+4
| | | | | | | | | - implement availability detection (available/registered/unknown) - integrate availability into domain results - add lightweight domain suggestions - introduce local watchlist with persistence - add WatchlistView and toolbar access - include availability in export
* bump versionv1.7.2Christian Cleberg2026-04-111-5/+7
|
* fix(services): rename unused URLSession delegate params to _v1.7.1Christian Cleberg2026-04-031-4/+4
|
* add custom port scans and improve DNS/email/security diagnosticsv1.7.0Christian Cleberg2026-04-031-4/+4
|
* Add BIMI and MTA-STS checks to email securityv1.5.0Christian Cleberg2026-04-031-4/+4
|
* Release 1.4.0v1.4.0Christian Cleberg2026-04-031-4/+4
| | | | | | | Add richer SSL/TLS inspection details including negotiated TLS version, cipher suite, full certificate chain display, crt.sh lookup, and HSTS preload status. Persist HSTS preload in history/export and run the preload check in parallel with the SSL lookup.
* DomainDig 1.3.0Christian Cleberg2026-04-031-4/+4
| | | | | | | | | - Add SOA, SRV, CAA, and DS DNS record lookups - Add DNSSEC status detection via RRSIG queries - Add configurable DNS-over-HTTPS resolver settings - Support Cloudflare, Google, Quad9, and custom HTTPS resolvers - Improve DoH compatibility with standards-based fallback handling - Keep DNS results UI compact with a single DNSSEC indicator
* fix: various bugsChristian Cleberg2026-04-031-4/+4
| | | | | | - fix Email section to left align - ensure container contents can overflow scroll but page cannot - fix map width
* realigning commitsChristian Cleberg2026-03-181-4/+19
|