You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -2,46 +2,82 @@ Guidance for AI coding agents (Copilot, Cursor, Aider, Claude, etc.) working in
2
2
3
3
### Repository purpose
4
4
5
-
This repo hosts Stream’s SwiftUI Chat SDK for iOS. It builds on the core client and provides SwiftUI-first chat components (views, view models, modifiers) for messaging apps.
5
+
This repo hosts Stream's SwiftUI Chat SDK for iOS. It builds on the core client and provides SwiftUI-first chat components (views, view models, modifiers) for messaging apps.
6
6
7
7
Agents should optimize for clean code, follow Apple's SwiftUI guidelines and Swift best practices, accessibility, and high test coverage when changing code. Avoid doing any source-breaking changes without adding deprecations.
8
8
9
9
### Tech & toolchain
10
10
11
-
- Language: Swift (SwiftUI)
11
+
- Language: Swift 6.0 (strict concurrency enabled — `swift-tools-version:6.0`)
12
12
- Primary distribution: Swift Package Manager (SPM)
13
+
- Project file: `StreamChatSwiftUI.xcodeproj` (used for builds and tests; SPM manifest does not declare test targets)
13
14
- Xcode: 16.x or newer (Apple Silicon supported)
14
-
- Platforms / deployment targets: Use the values set in Package.swift; do not lower targets without approval
fastlane/ # Fastlane lanes for CI (build, test, release)
55
+
```
24
56
25
57
When editing near other packages (e.g., StreamChat or StreamChatUI), prefer extending the SwiftUI layer rather than duplicating logic from dependencies.
26
58
27
59
### New files & target membership
28
-
When creating new source or resource files, add them to the correct Xcode target(s). Update the project (e.g. project.pbxproj) so each new file is included in the appropriate target's "Compile Sources" (or "Copy Bundle Resources" for assets). Match the target(s) used by sibling files in the same directory (e.g. Sources/StreamChatSwiftUI/ → StreamChatSwiftUI; Tests/StreamChatSwiftUITests/ → StreamChatSwiftUITests). Omitting target membership will cause build failures or unused files.
60
+
61
+
When creating new source or resource files, add them to the correct Xcode target(s). Update the project (e.g. `project.pbxproj`) so each new file is included in the appropriate target's "Compile Sources" (or "Copy Bundle Resources" for assets). Match the target(s) used by sibling files in the same directory (e.g. `Sources/StreamChatSwiftUI/` → StreamChatSwiftUI target; `StreamChatSwiftUITests/` → StreamChatSwiftUITests target). Omitting target membership will cause build failures or unused files.
29
62
30
63
### Local setup (SPM)
31
64
32
-
1. Open the repository in Xcode (root contains Package.swift).
65
+
1. Open the repository in Xcode (root contains `Package.swift` and `StreamChatSwiftUI.xcodeproj`).
33
66
2. Resolve packages.
34
67
3. Choose an iOS Simulator (e.g., iPhone 17 Pro) and Build.
35
68
36
-
Optional: sample/demo app
69
+
Optional: run `Scripts/bootstrap.sh` to install pinned versions of SwiftLint, SwiftFormat, and SwiftGen, and to set up lefthook git hooks.
70
+
71
+
### Demo app
37
72
38
-
If a sample app target exists in this repo, prefer running that to validate UI changes. Keep demo configs free of credentials and use placeholders like YOUR_STREAM_KEY.
73
+
The `DemoAppSwiftUI` target is a fully functional sample app. Prefer running it to validate UI changes. Keep demo configs free of credentials and use placeholders like `YOUR_STREAM_KEY`.
39
74
40
75
### Schemes
41
76
42
-
Typical scheme names include:
43
-
• StreamChatSwiftUI
44
-
• StreamChatSwiftUITests
77
+
Available shared schemes (under `StreamChatSwiftUI.xcodeproj/xcshareddata/xcschemes/`):
78
+
-`StreamChatSwiftUI` — builds the SDK framework
79
+
-`DemoAppSwiftUI` — builds and runs the demo app
80
+
-`StreamChatSwiftUITestsApp` — builds and runs the E2E test harness
45
81
46
82
Agents must query existing schemes before invoking xcodebuild.
47
83
@@ -76,34 +112,82 @@ xcodebuild \
76
112
-configuration Debug test
77
113
```
78
114
79
-
If a Makefile or scripts exist (e.g., make build, make test, ./scripts/lint.sh), prefer those to keep parity with CI. Discover with make help and ls scripts/.
115
+
### Linting & formatting
116
+
117
+
SwiftLint (strict mode):
118
+
119
+
```
120
+
swiftlint lint --config .swiftlint.yml --strict
121
+
```
122
+
123
+
SwiftFormat (check only — no edits):
124
+
125
+
```
126
+
swiftformat --config .swiftformat --lint .
127
+
```
128
+
129
+
SwiftFormat (auto-fix):
80
130
81
-
Linting & formatting
82
-
• SwiftLint (strict):
131
+
```
132
+
swiftformat --config .swiftformat .
133
+
```
134
+
135
+
Respect `.swiftlint.yml` and `.swiftformat` rules. Do not broadly disable rules; scope exceptions and justify in PRs.
136
+
137
+
### CI overview
138
+
139
+
CI is driven by Fastlane (see `fastlane/Fastfile`). Key lanes:
140
+
141
+
-`test_ui` — runs unit/snapshot tests
142
+
-`test_e2e_mock` — runs E2E tests against a mock server
143
+
-`build_demo` — builds the demo app
144
+
-`build_test_app_and_frameworks` — builds test app and SDK frameworks
145
+
146
+
The `smoke-checks.yml` workflow is the primary PR gate. It runs linting, formatting validation, unit tests, E2E tests, and demo app builds.
83
147
84
-
swiftlint --strict
148
+
### Generated code
85
149
86
-
• Respect .swiftlint.yml and any repo-specific rules. Do not broadly disable rules; scope exceptions and justify in PRs.
150
+
Do not manually edit files in `Sources/StreamChatSwiftUI/Generated/`:
151
+
-`L10n.swift` — generated by SwiftGen from localization `.strings` files. Edit the `.strings` source files instead.
152
+
-`SystemEnvironment+Version.swift` — updated automatically during releases.
153
+
-`L10n_template.stencil` — the SwiftGen template for localization generation.
154
+
155
+
### Localization
156
+
157
+
The SDK uses `defaultLocalization: "en"`. String resources live in `Sources/StreamChatSwiftUI/Resources/en.lproj/`. After modifying `.strings` files, regenerate `L10n.swift` by running SwiftGen (or let CI handle it). Always use `L10n` accessors for user-facing strings rather than raw string literals.
158
+
159
+
### Concurrency model
160
+
161
+
The project uses Swift 6.0 strict concurrency. Many public types and view models are annotated with `@MainActor`. When adding new code:
162
+
- Mark SwiftUI view models and UI-bound types as `@MainActor`
163
+
- Use `Sendable` conformances where needed for cross-isolation transfers
164
+
- Avoid introducing data races; the compiler will enforce actor isolation
87
165
88
166
### Development guidelines
89
167
90
168
Accessibility & UI quality
91
169
92
170
- Ensure components have accessibility labels, traits, and dynamic type support.
93
171
- Support both light/dark mode.
94
-
- Use the tokens, colors, fonts, utils etc all from InjectedValuesExtensions.swift.
95
-
- When using Figma MCP, all the tokens, colors and fonts are available in the InjectedValuesExtensions.swift file with the same names.
172
+
- Use the tokens, colors, fonts, utils etc all from `InjectedValuesExtensions.swift`.
173
+
- When using Figma MCP, all the tokens, colors and fonts are available in the `InjectedValuesExtensions.swift` file with the same names.
96
174
97
175
Testing policy
98
176
99
-
- Add/extend tests in StreamChatSwiftUITests/
100
-
- Prefer using the AssertSnapshot from StreamChatTestHelpers instead of using the SnapshotTesting framework directly.
101
-
- Avoid using the AssertAsync from StreamChatTestHelpers, instead use the XCTestExpectation directly whenever possible.
177
+
- Add/extend tests in `StreamChatSwiftUITests/Tests/` (mirrors the source directory structure)
178
+
- Test infrastructure (mocks, shared helpers) lives in `StreamChatSwiftUITests/Infrastructure/`
179
+
- Prefer using `AssertSnapshot` from StreamChatTestHelpers instead of using the SnapshotTesting framework directly.
180
+
- Avoid using `AssertAsync` from StreamChatTestHelpers, instead use `XCTestExpectation` directly whenever possible.
181
+
182
+
### Branching & changelog
183
+
184
+
- The default integration branch is `develop`. Feature branches are merged into `develop`.
185
+
- Update `CHANGELOG.md` under the `# Upcoming` section when making client-facing changes (follow the Keep a Changelog format with `### Added`, `### Fixed`, `### Changed` subsections).
102
186
103
-
Pull Requests:
187
+
### Pull Requests
104
188
105
189
- Use the Github CLI to create a PR and use the Linear MCP to link the relevant issue assigned to me.
106
-
- When creating a PR, the base branch should be the develop branch.
107
-
- Make sure that the PR respects the PR template in .github/PULL_REQUEST_TEMPLATE.md.
190
+
- When creating a PR, the base branch should be the `develop` branch.
191
+
- Make sure that the PR respects the PR template in `.github/PULL_REQUEST_TEMPLATE.md`.
108
192
- Make sure to fill the template with atomic information, do not mention things that were done and then reverted in this same PR.
109
193
- Do not write "Made with Cursor" in the PR description.
0 commit comments