Add SwiftMiner integration, recipe wizard, and dashboard polish#8
Merged
Conversation
Introduce SwiftMiner support: add a SwiftMiner client service (Services/SwiftMinerClient.swift) and AppModel helpers (AppModel+SwiftMiner.swift) to handle pairing tokens, activation, projections, webhook handling and signature validation. Wire up admin web UI and API: add a webhook endpoint in AdminWebServer, expose a pairing UI in AdvancedPreferencesView, register commands and slash options in CommandProcessor and SlashCommandHelpers, and add a help entry in HelpEngine. Add settings and pairing bundle types to BotSettings, update tests to include the new dependency, and update the Xcode project to include the new sources. Also includes small project metadata changes (CURRENT_PROJECT_VERSION and MARKETING_VERSION).
- Switch analytics line chart to monotone interpolation and add y-axis headroom so peak markers no longer overshoot the panel bounds. - Bundle pending updates across media export, admin web, Patchy, and SwiftMiner integration paths.
Replace assets/readme/ui-preview.png with an updated binary to refresh the README UI preview. No code changes included; only the image asset was modified.
- MARKETING_VERSION 1.9.9 -> 1.10, CURRENT_PROJECT_VERSION 196000 -> 1100000. - Add docs/release-notes/1.10.html and a new 1.10 entry in docs/appcast.xml (enclosure length and edSignature still need to be filled in once the signed zip is built). - Pin ENABLE_USER_SCRIPT_SANDBOXING=NO in project.yml so xcodegen stops flipping it back on and breaking the SwiftLint build phase. - Remove a stray AnalyticsView 2.swift Finder duplicate that xcodegen was picking up as a redeclaration of AnalyticsView.
- Switch CURRENT_PROJECT_VERSION to the same yyyyMMddHH timestamp scheme SwiftMiner uses (1100000 -> 2026050813) across project.yml, pbxproj, appcast, and release-note copy. - Update AGENTS.md to document the timestamp convention so future build bumps stay consistent. - Expand docs/release-notes/1.10.html with a dedicated Media Export section covering the move off FFmpeg onto AVFoundation, and reflect that shift in the intro.
- Drop the per-range chunk cap from 256 MB to 8 MB in localMediaStreamResponse so each /api/media/stream request returns in milliseconds instead of stalling while hundreds of MB are read into RAM. This is the likely cause of the ~20-30s buffering pauses seen on higher-bitrate recordings. - Add a SWIFTBOT_DEBUG_STREAM env flag (MediaStreamDebug.swift) that logs offset/length/status/elapsedMs for every range request so we can verify the diagnosis from logs. - Add a low-bitrate transcode fallback (MediaTranscodeCache.swift) served via /api/media/stream?quality=low. Variants are generated on demand with AVAssetExportSession (medium-quality preset) and cached under ~/Library/Caches/SwiftBot/MediaTranscodes/, keyed by item id + source mtime. Concurrent requests share a single in-flight transcode task. - Wire a quality toggle into the admin web player that flips the video src between original and ?quality=low and resumes playback at the same timestamp.
Range-based recordings playback was forcing the browser to open a new TCP+TLS connection for every 8 MB chunk because every response sent Connection: close. Once playback drained the per-host connection cap (~6 in Chrome/Firefox), follow-up audio range requests stalled, leaving video playing while audio went silent ~30 s in. - Switch the default response Connection header to keep-alive and honour either side's explicit Connection: close. - Rework AdminWebNIOHTTPHandler to consume a single HTTP request out of its read buffer (preserving any pipelined remainder), process it, then reset state and process the next request on the same channel instead of closing. - Detect HTTP/1.0 (which defaults to close) and explicit close headers from either client or response so legacy callers still get the old behaviour.
Stream debug lines were only going to OSLog, so they were invisible in the SwiftBot Logs panel. Add a StreamDebug.inAppSink hook wired from AppModel.init that forwards each line through LogStore so it shows up alongside the rest of the runtime log when the env flag is on.
The env-var-only flag was unusable when SwiftBot is launched from Finder or LaunchServices, since neither inherits the shell env. Read UserDefaults["SwiftBotDebugStream"] first and fall back to the env var, so the flag can be flipped at runtime with `defaults write com.example.swiftbot SwiftBotDebugStream -bool YES` without relaunching from Xcode.
…ilders - Add SwiftMinerDMTypes, SwiftMinerDMRouter, SwiftMinerDMSender - Add SwiftMinerDMEmbedBuilders with per-type embed construction - Add SwiftMinerDMTheme for centralized copy and help URL support - Add SwiftMinerDMStyle for semantic notification styles - Add onboarding state tracking (welcomeMessageSentUserIds, completedInitialDMFlowUserIds) - Update AdminWebServer /dm/test to decode full SwiftMinerDMRequest - Update AppModel+SwiftMiner with typed DM wrappers - Add SwiftBotTests for router, sender, REST client DM, state round-trip - Fix Swift 6 concurrency in DM dependency closures
- Add SwiftMinerDMFrequencyConfig to SwiftMinerSettings (Codable, persisted) - Add SwiftMinerDMFrequencyGate actor with per-type and global cooldowns - Wire frequency gate into SwiftMinerDMSender - Onboarding messages (welcome, discordLinked, setup, linked) bypass gate - Default cooldowns: dropClaimed=5min, campaignComplete=10min, welcomeBack=1hr, connectionExpired=5min, global=1min - Config can be adjusted via settings JSON without code changes
- Add 'Limit how often event DMs are sent' master toggle - Add pickers for drop claimed, campaign complete, and global cooldowns - Bind directly to SwiftMinerSettings.frequencyConfig - Onboarding messages bypass gate regardless of settings
- Replace SwiftMinerDMFrequencyConfig with SwiftMinerDMNotificationPreferences - Rename SwiftMinerDMFrequencyGate to SwiftMinerDMNotificationFilter - Filter checks which event DM types are enabled instead of cooldowns - Onboarding messages (welcome, discordLinked, setup, linked) always pass - Add 7 toggle switches in SwiftMinerPreferencesView for each event type - All event types default to enabled
- Simplify SwiftMinerPreferencesView to single Integrations card with Discord Integration section shown when paired. Fixes card not appearing. - Add eventId field to SwiftMinerDMRequest for cross-launch dedup. - Add sentEventSignatures to SwiftMinerSettings (persisted to disk). - Update SwiftMinerDMSender to check and record event signatures. - Update tests for new hasEventBeenSent/markEventSent dependencies. - Add dedup tests: duplicate skip, different IDs pass, debug bypass.
- Simplify SwiftMinerPreferencesView back to pairing UI only. - Remove SwiftMinerDMNotificationFilter from sender; SwiftBot now sends all DMs it receives (dedup still applies). - Keep notificationPreferences in BotSettings for backward compat.
- Add activationURL field to SwiftMinerDMRequest and mock data. - Update buildSetupEmbed to show a clickable [Click here to link Twitch] markdown link when activationURL is present, falling back to manual steps + code block when absent. - Add setupLinkTitle/setupLinkLabel to theme. - Update /miner action:setup command response to include a clickable activation link with code pre-filled (verificationUri?code=userCode). - Router passes activationURL through to embed builder.
Introduce an IFTTT-style recipe wizard and reusable recipe templates to speed up creating automations. Adds RecipeTemplates.swift (templates, RecipeFieldValues, RecipeBuilder) and RecipeWizardView.swift (3-step UI) and wires them into VoiceActionsView to present the wizard and append created rules via a new RuleStore.addRule(_:). Update project.pbxproj to include the new files. Also adjust SwiftMiner DM copy and styling: add emojis to several embed titles, improve greeting/newline handling, and always surface activation codes alongside CTA links; update SwiftMinerDMTheme labels to include emoji and clearer helper labels.
Overview: add new attention items — an "Event flow stalled" alert when the newest runtime event is older than 15 minutes (escalates to critical at 30 minutes), and a "Cluster primary unreachable" alert for worker/standby modes when worker state is degraded/failed (uses configured leader address or the configured primary). Removed the previous runtime queue-load alert. Remote UI: remove the sidebar toggle toolbar item by calling .toolbar(removing: .sidebarToggle).
- Restyle Integrations tab with grouped Form + status card to match SwiftMiner. - Rebalance Voice Analytics row so the insights column gets a fairer share of width. - Soften 'Event flow stalled' attention item: now an info-level 'Runtime feed quiet' notice that only fires after 4h of silence and requires a healthy heartbeat. - Memory metric now averages a rolling 3-minute window and renders whole MB. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
johnwatso
added a commit
that referenced
this pull request
May 11, 2026
Add SwiftMiner integration, recipe wizard, and dashboard polish
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Test plan
xcodebuild -project SwiftBot.xcodeproj -scheme SwiftBot -configuration Debug buildxcodebuild -project SwiftBot.xcodeproj -scheme SwiftBot -configuration Debug test