Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
03bd9bb
Add SwiftMiner integration (client, UI, webhooks)
johnwatso May 5, 2026
67b2c17
Enable SwiftMiner pairing server
johnwatso May 6, 2026
b9c6854
Polish SwiftBot sidebar
johnwatso May 6, 2026
54dcfde
Update README style and switch license to MIT
johnwatso May 6, 2026
c2940cd
Add security policy
johnwatso May 6, 2026
5437acc
Remove vulnerability reporting section
johnwatso May 6, 2026
7ad5a76
Clarify app-owned security components
johnwatso May 6, 2026
bcd35fb
Polish SwiftMiner pairing and dashboard UX
johnwatso May 7, 2026
c95946b
Integrate SwiftMiner Discord linking
johnwatso May 7, 2026
c9660fe
Polish SwiftMiner setup DM and docs
johnwatso May 7, 2026
c6065e1
Add native and web analytics dashboard
johnwatso May 7, 2026
2bee074
Commit remaining local changes
johnwatso May 7, 2026
234a057
Polish analytics chart and refresh integrations
johnwatso May 8, 2026
8275822
Update UI preview image
johnwatso May 8, 2026
84bb491
Bump SwiftBot to 1.10
johnwatso May 8, 2026
1b9bb1f
Adopt timestamp build numbers and expand 1.10 release notes
johnwatso May 8, 2026
d1b281a
Improve recordings playback streaming
johnwatso May 8, 2026
aebb664
Enable HTTP keep-alive on the admin web server
johnwatso May 8, 2026
c4464c6
Mirror SWIFTBOT_DEBUG_STREAM lines into in-app Logs
johnwatso May 8, 2026
d0ecde2
Allow SwiftBotDebugStream toggle via UserDefaults
johnwatso May 8, 2026
bde0121
Fix sidebar header resize alignment
johnwatso May 8, 2026
7865467
Refine main window chrome layout
johnwatso May 8, 2026
427e593
Remove legacy prefix command support
johnwatso May 8, 2026
fe63bb6
Improve analytics dashboard insights and persistence
johnwatso May 8, 2026
e40826d
Redesign overview and analytics dashboards
johnwatso May 9, 2026
c9db786
feat: typed SwiftMiner DM pipeline with onboarding state and embed bu…
johnwatso May 9, 2026
7b13dc8
docs: add Discord help page for SwiftMiner DMs
johnwatso May 9, 2026
7d9aaef
docs: move discord help to docs/help/ for future expansion
johnwatso May 9, 2026
354d496
docs: remove discord help (moving to SwiftMiner repo)
johnwatso May 9, 2026
2882fc5
feat: add default help documentation URL to DM theme
johnwatso May 9, 2026
5e50681
feat: add DM frequency gate to prevent notification bombardment
johnwatso May 9, 2026
2399449
feat: add DM frequency controls to SwiftMiner preferences UI
johnwatso May 9, 2026
5a358fd
feat: replace frequency gate with per-type DM notification toggles
johnwatso May 9, 2026
d0a3a23
feat: move DM notification toggles into separate Discord Integration …
johnwatso May 9, 2026
e878af1
fix: show Discord Integration card regardless of SwiftMiner pairing s…
johnwatso May 9, 2026
a0d033a
Fix Discord Integration settings UI and add persistent DM dedup
johnwatso May 9, 2026
b6e6a8c
Remove DM notification toggles from SwiftBot preferences
johnwatso May 9, 2026
fd1f072
Add activationURL to setup DM for one-click Twitch linking
johnwatso May 9, 2026
6a05a7e
Add recipe wizard and templates
johnwatso May 10, 2026
6ba1c88
Add event/cluster alerts; remove sidebar toggle
johnwatso May 11, 2026
ca2b78c
Polish SwiftMiner tab, Voice Analytics, and overview metrics
johnwatso May 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# SwiftBot Agent Notes

Read `AI_CONTEXT.md` first. It is the main architecture and workflow reference for AI agents working in this repo.

This file exists to capture the practical guardrails that agents are most likely to miss: build system boundaries, project generation, versioning, and release metadata discipline.

## Project Shape

- SwiftBot is a native macOS Xcode app built with SwiftUI.
- The app project is generated from `project.yml` using XcodeGen.
- This repo also contains one nested Swift package at `Sources/UpdateEngine`.
- Do not convert the main app into a Swift package.
- Do not introduce a repo-root `Package.swift`.
- Do not move app files into a package-style layout.

## Build and Test

For the main app, use Xcode tooling:

```sh
xcodebuild -project SwiftBot.xcodeproj -scheme SwiftBot -configuration Debug build
xcodebuild -project SwiftBot.xcodeproj -scheme SwiftBot -configuration Debug test
```

Run `xcodegen` after editing `project.yml`:

```sh
xcodegen
```

For the nested UpdateEngine package only, SwiftPM commands are valid inside `Sources/UpdateEngine` when that package is the thing being changed:

```sh
cd Sources/UpdateEngine
swift test
```

Do not use `swift build` or `swift test` as a substitute for validating the app target.

## Scope Discipline

- Keep changes scoped to the user’s request.
- Prefer modifying the relevant SwiftUI view, model, or service directly instead of refactoring unrelated systems.
- Do not introduce new modules, packages, or architectural layers unless the user explicitly asks for that level of change.
- Follow existing Apple-platform patterns in this repo. Avoid web-style UI abstractions and avoid external UI frameworks.

## Versioning

- `MARKETING_VERSION` is user-directed. Do not bump it unless the user explicitly asks.
- `CURRENT_PROJECT_VERSION` is timestamp-based. Update it whenever release/version/build preparation is part of the requested work. Use the local project time at the moment of the change, formatted as `yyyyMMddHH` (example: `2026050813` means 2026 May 8 at 1pm).
- When version metadata changes, keep `project.yml` and `SwiftBot.xcodeproj/project.pbxproj` aligned.
- If release metadata is touched, also verify related Sparkle/appcast files under `docs/`:
- `sparkle:shortVersionString` should match `MARKETING_VERSION`.
- `sparkle:version` should match the generated `CURRENT_PROJECT_VERSION` timestamp.
- Any visible build references in release notes should match the generated build number.

## Sparkle and Release Metadata

Treat these as release-critical whenever touched:

- `project.yml`
- `SwiftBot.xcodeproj/project.pbxproj`
- `docs/appcast.xml`
- `docs/release-notes/*`

Do not break:

- `SUFeedURL`
- `SUPublicEDKey`
- `MARKETING_VERSION`
- `CURRENT_PROJECT_VERSION`
- appcast version/release-note links

If you edit release metadata, build the app and verify the resulting Info.plist values before calling the work done.

## Project Generation Rules

- `project.yml` is the source of truth for generated Xcode settings.
- If you change build settings in the generated project, mirror them in `project.yml` unless there is a very specific reason not to.
- Avoid committing unrelated XcodeGen drift.

## Coordination

- Use `AI_CONTEXT.md` for architecture, file ownership, cluster safety rules, and UI rules.
- If guidance in this file and `AI_CONTEXT.md` ever appear to conflict, follow the repo reality and preserve existing behavior, then document the inconsistency in your final note.
38 changes: 15 additions & 23 deletions AI_CONTEXT.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ SwiftBot is a **native macOS Discord bot manager** built entirely with Swift and

| Property | Value |
|----------|-------|
| Platform | macOS 13+ |
| Platform | macOS 26+ |
| Language | Swift with Concurrency (async/await, actors) |
| Framework | SwiftUI — Apple-platform-first, no web frameworks |
| Design Language | Apple Human Interface Guidelines — Liquid Glass / modern macOS |
| Architecture | MVVM + actor isolation + EventBus pub/sub |
| Build System | Xcode + Swift Package Manager |
| Build System | Xcode + XcodeGen for the app, SwiftPM only for `Sources/UpdateEngine` |

**What it does:** Connects to Discord via WebSocket gateway, monitors server events, and executes automated rules when events match. Also supports AI replies, wiki lookups, update monitoring (Patchy), multi-node cluster failover (SwiftMesh), and a web-based admin UI.

Expand Down Expand Up @@ -99,7 +99,7 @@ struct PipelineContext {
| File | Purpose |
|------|---------|
| `AppModel.swift` | Primary app state `@MainActor ObservableObject`. Bot lifecycle, settings, gateway coordination, rule engine orchestration, Patchy scheduler, plugin management. |
| `AppModel+Commands.swift` | Slash and prefix command handlers |
| `AppModel+Commands.swift` | Slash command handlers |
| `AppModel+Gateway.swift` | Gateway event parsing and dispatch |
| `AppModel+AI.swift` | AI provider routing and response generation |
| `DiscordService.swift` | Discord WebSocket gateway + REST API actor. Rule action execution. AI replies. Wiki lookup. |
Expand Down Expand Up @@ -163,7 +163,7 @@ All UI in SwiftBot **must** follow:

1. **Apple Human Interface Guidelines** — always, without exception
2. **SwiftUI only** — no AppKit views unless unavoidable (use `NSViewRepresentable`)
3. **System Settings layout style** — sidebar navigation, HSplitView, material backgrounds
3. **System Settings layout style** — sidebar navigation, split-pane layouts where appropriate, material backgrounds
4. **Liquid Glass / modern macOS design language** — `.ultraThinMaterial`, `.thinMaterial`, semantic system colors
5. **No web-style patterns** — no CSS-like layouts, no custom scrollbars, no card grids
6. **No external UI frameworks** — zero SwiftPM UI dependencies
Expand All @@ -179,7 +179,7 @@ All UI in SwiftBot **must** follow:
### 3-Pane View Architecture

```
VoiceWorkspaceView (HSplitView)
VoiceWorkspaceView (split-pane layout)
├── RuleListView (220–320px) — VoiceRuleListView.swift
│ ├── isLoading → ProgressView()
│ ├── rules.isEmpty → RuleListEmptyStateView ("No Rules Yet")
Expand Down Expand Up @@ -233,7 +233,8 @@ var processedActions: [RuleAction] // runtime migration: legacy booleans → m

- ✅ Swift Concurrency (`async/await`, `actor`, `@MainActor`, `Task`)
- ✅ Keychain for ALL secrets — never write to disk
- ✅ Add new `.swift` files to `project.pbxproj` (4 entries: PBXFileReference, PBXBuildFile, PBXGroup, PBXSourcesBuildPhase)
- ✅ Treat `project.yml` as the source of truth for app project settings
- ✅ Run `xcodegen` after editing `project.yml`
- ✅ `.id(selectionID)` on all list-detail views to prevent SwiftUI state leakage
- ✅ Look up current selection INSIDE binding closures — never capture IDs at creation time
- ✅ `await MainActor.run {}` when updating `@Published` from background actors
Expand All @@ -245,7 +246,8 @@ var processedActions: [RuleAction] // runtime migration: legacy booleans → m
- ❌ Pre-populate new rules with default trigger or actions
- ❌ Change `Models.swift` structure without cross-agent approval
- ❌ Add new SwiftPM dependencies without explicit justification
- ❌ Break existing UI layouts or SplitView behaviors
- ❌ Convert the main app target into a Swift package or add a repo-root `Package.swift`
- ❌ Break existing UI layouts or split-pane behaviors
- ❌ Send Discord output from Standby or Worker nodes
- ❌ Use `#if DEBUG` to gate production logic
- ❌ Call `test*` methods from production code paths
Expand All @@ -255,20 +257,11 @@ var processedActions: [RuleAction] // runtime migration: legacy booleans → m

---

## 8. Multi-Agent File Ownership
## 8. Agent Coordination

When multiple agents work on SwiftBot simultaneously, respect file ownership:
If multiple agents are working in parallel, coordinate before editing the same files and prefer clear ownership by area for the duration of the task.

| File | Owner |
|------|-------|
| `VoiceActionsView.swift` | **claude** |
| `VoiceRuleListView.swift` | **claude** |
| `EmptyRuleOnboardingView.swift` | **claude** |
| `Models.swift` | **kimi** |
| `AppModel.swift` | **gemini** |
| `DiscordService.swift` | **gemini** |

**Rule:** Post in `#swiftbotdev` before editing another agent's file. Coordinate task splits before starting any work.
This file does not assign permanent file owners. Treat any historical ownership notes elsewhere as advisory, not authoritative.

---

Expand Down Expand Up @@ -306,11 +299,10 @@ static func empty() -> Rule { Rule(trigger: nil, actions: []) }
- [ ] Build succeeds — 0 errors, 0 new warnings
- [ ] Modified feature works as expected
- [ ] No regressions in unrelated features
- [ ] `CHANGELOG.md` updated
- [ ] Any new `.swift` files added to `project.pbxproj`
- [ ] Posted results in `#swiftbotdev`
- [ ] If `project.yml` changed, regenerate with `xcodegen`
- [ ] If versioning or release metadata changed, verify `project.yml`, `SwiftBot.xcodeproj/project.pbxproj`, and `docs/` stay aligned

---

*Last updated: 2026-03-11*
*Last updated: 2026-05-07*
*See `ARCHITECTURE.md` for full technical detail · `AI_GUIDE.md` for common task recipes*
2 changes: 0 additions & 2 deletions AI_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,6 @@ Binding(

When modifying this project, update these files:

- [ ] **CHANGELOG.md** - Document what changed and why
- [ ] **This file** - If you discover new patterns or gotchas
- [ ] **ARCHITECTURE.md** - If you change core architecture

Expand Down Expand Up @@ -435,7 +434,6 @@ Before marking changes complete:
- [ ] Modified features work as expected
- [ ] Existing features still work (no regressions)
- [ ] Settings persist across restart
- [ ] CHANGELOG.md updated
- [ ] No console errors or warnings

## Resources
Expand Down
Loading
Loading