buildanything 1.7.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +55 -0
- package/README.md +71 -61
- package/agents/ios-app-review-guardian.md +49 -0
- package/agents/ios-foundation-models-specialist.md +46 -0
- package/agents/ios-storekit-specialist.md +52 -0
- package/agents/ios-swift-architect.md +102 -0
- package/agents/ios-swift-search.md +130 -0
- package/agents/ios-swift-ui-design.md +104 -0
- package/commands/build.md +80 -176
- package/commands/fix.md +65 -0
- package/commands/setup.md +73 -0
- package/commands/ux-review.md +63 -0
- package/commands/verify.md +72 -0
- package/hooks/session-start +18 -1
- package/package.json +5 -2
- package/protocols/brainstorm.md +99 -0
- package/protocols/build-fix.md +52 -0
- package/protocols/cleanup.md +54 -0
- package/protocols/design.md +269 -0
- package/protocols/eval-harness.md +61 -0
- package/protocols/fake-data-detector.md +64 -0
- package/protocols/ios-context.md +235 -0
- package/protocols/ios-frameworks-map.md +323 -0
- package/protocols/ios-phase-branches.md +162 -0
- package/protocols/ios-preflight.md +27 -0
- package/protocols/metric-loop.md +93 -0
- package/protocols/planning.md +87 -0
- package/protocols/smoke-test.md +110 -0
- package/protocols/verify.md +67 -0
- package/protocols/web-phase-branches.md +201 -0
- package/skills/ios/_VENDORED.md +60 -0
- package/skills/ios/activitykit/LICENSE +131 -0
- package/skills/ios/activitykit/SKILL.md +505 -0
- package/skills/ios/activitykit/references/activitykit-patterns.md +868 -0
- package/skills/ios/app-intents/LICENSE +131 -0
- package/skills/ios/app-intents/SKILL.md +494 -0
- package/skills/ios/app-intents/references/appintents-advanced.md +1076 -0
- package/skills/ios/apple-on-device-ai/LICENSE +131 -0
- package/skills/ios/apple-on-device-ai/SKILL.md +505 -0
- package/skills/ios/apple-on-device-ai/references/coreml-conversion.md +425 -0
- package/skills/ios/apple-on-device-ai/references/coreml-optimization.md +344 -0
- package/skills/ios/apple-on-device-ai/references/foundation-models.md +508 -0
- package/skills/ios/apple-on-device-ai/references/mlx-swift.md +285 -0
- package/skills/ios/ios-26-platform/SKILL.md +53 -0
- package/skills/ios/ios-26-platform/references/automatic-adoption.md +161 -0
- package/skills/ios/ios-26-platform/references/backward-compat.md +238 -0
- package/skills/ios/ios-26-platform/references/liquid-glass.md +255 -0
- package/skills/ios/ios-26-platform/references/swiftui-apis.md +277 -0
- package/skills/ios/ios-26-platform/references/toolbar-navigation.md +250 -0
- package/skills/ios/ios-bootstrap/SKILL.md +98 -0
- package/skills/ios/ios-bootstrap/references/apple-docs-mcp-config.md +28 -0
- package/skills/ios/ios-bootstrap/references/new-project-dialog.md +41 -0
- package/skills/ios/ios-bootstrap/references/xcode-mcp-config.md +29 -0
- package/skills/ios/ios-debugger-agent/LICENSE +21 -0
- package/skills/ios/ios-debugger-agent/SKILL.md +58 -0
- package/skills/ios/ios-debugger-agent/agents/openai.yaml +4 -0
- package/skills/ios/ios-entitlements-generator/SKILL.md +47 -0
- package/skills/ios/ios-hig/SKILL.md +41 -0
- package/skills/ios/ios-hig/references/accessibility.md +81 -0
- package/skills/ios/ios-hig/references/content.md +142 -0
- package/skills/ios/ios-hig/references/feedback.md +123 -0
- package/skills/ios/ios-hig/references/interaction.md +199 -0
- package/skills/ios/ios-hig/references/performance-platform.md +129 -0
- package/skills/ios/ios-hig/references/privacy-permissions.md +181 -0
- package/skills/ios/ios-hig/references/visual-design.md +84 -0
- package/skills/ios/ios-info-plist-hardening/SKILL.md +130 -0
- package/skills/ios/ios-maestro-flow-author/SKILL.md +68 -0
- package/skills/ios/ios-maestro-flow-author/references/input-and-scroll.yaml +17 -0
- package/skills/ios/ios-maestro-flow-author/references/modal-and-dismiss.yaml +14 -0
- package/skills/ios/ios-maestro-flow-author/references/onboarding-flow.yaml +16 -0
- package/skills/ios/ios-maestro-flow-author/references/tab-navigation.yaml +13 -0
- package/skills/ios/ios-maestro-flow-author/references/tap-and-assert.yaml +9 -0
- package/skills/ios/swift-accessibility/LICENSE +21 -0
- package/skills/ios/swift-accessibility/SKILL.md +371 -0
- package/skills/ios/swift-accessibility/examples/before-after-appkit.md +446 -0
- package/skills/ios/swift-accessibility/examples/before-after-swiftui.md +441 -0
- package/skills/ios/swift-accessibility/examples/before-after-uikit.md +464 -0
- package/skills/ios/swift-accessibility/references/assistive-access.md +441 -0
- package/skills/ios/swift-accessibility/references/display-settings.md +491 -0
- package/skills/ios/swift-accessibility/references/dynamic-type.md +420 -0
- package/skills/ios/swift-accessibility/references/media-accessibility.md +421 -0
- package/skills/ios/swift-accessibility/references/motor-input.md +393 -0
- package/skills/ios/swift-accessibility/references/nutrition-labels.md +362 -0
- package/skills/ios/swift-accessibility/references/platform-specifics.md +515 -0
- package/skills/ios/swift-accessibility/references/semantic-structure.md +585 -0
- package/skills/ios/swift-accessibility/references/testing-auditing.md +507 -0
- package/skills/ios/swift-accessibility/references/voice-control.md +317 -0
- package/skills/ios/swift-accessibility/references/voiceover-swiftui.md +584 -0
- package/skills/ios/swift-accessibility/references/voiceover-uikit.md +519 -0
- package/skills/ios/swift-accessibility/references/wcag-mapping.md +167 -0
- package/skills/ios/swift-accessibility/resources/audit-template.swift +128 -0
- package/skills/ios/swift-accessibility/resources/qa-checklist.md +258 -0
- package/skills/ios/swift-concurrency/LICENSE +21 -0
- package/skills/ios/swift-concurrency/SKILL.md +171 -0
- package/skills/ios/swift-concurrency/references/_index.md +50 -0
- package/skills/ios/swift-concurrency/references/actors.md +660 -0
- package/skills/ios/swift-concurrency/references/async-algorithms.md +847 -0
- package/skills/ios/swift-concurrency/references/async-await-basics.md +266 -0
- package/skills/ios/swift-concurrency/references/async-sequences.md +710 -0
- package/skills/ios/swift-concurrency/references/core-data.md +560 -0
- package/skills/ios/swift-concurrency/references/glossary.md +135 -0
- package/skills/ios/swift-concurrency/references/linting.md +155 -0
- package/skills/ios/swift-concurrency/references/memory-management.md +569 -0
- package/skills/ios/swift-concurrency/references/migration.md +1104 -0
- package/skills/ios/swift-concurrency/references/performance.md +593 -0
- package/skills/ios/swift-concurrency/references/sendable.md +598 -0
- package/skills/ios/swift-concurrency/references/tasks.md +636 -0
- package/skills/ios/swift-concurrency/references/testing.md +592 -0
- package/skills/ios/swift-concurrency/references/threading.md +495 -0
- package/skills/ios/swift-security-expert/LICENSE +21 -0
- package/skills/ios/swift-security-expert/SKILL.md +470 -0
- package/skills/ios/swift-security-expert/references/biometric-authentication.md +565 -0
- package/skills/ios/swift-security-expert/references/certificate-trust.md +592 -0
- package/skills/ios/swift-security-expert/references/common-anti-patterns.md +690 -0
- package/skills/ios/swift-security-expert/references/compliance-owasp-mapping.md +537 -0
- package/skills/ios/swift-security-expert/references/credential-storage-patterns.md +721 -0
- package/skills/ios/swift-security-expert/references/cryptokit-public-key.md +505 -0
- package/skills/ios/swift-security-expert/references/cryptokit-symmetric.md +497 -0
- package/skills/ios/swift-security-expert/references/keychain-access-control.md +508 -0
- package/skills/ios/swift-security-expert/references/keychain-fundamentals.md +596 -0
- package/skills/ios/swift-security-expert/references/keychain-item-classes.md +476 -0
- package/skills/ios/swift-security-expert/references/keychain-sharing.md +458 -0
- package/skills/ios/swift-security-expert/references/migration-legacy-stores.md +727 -0
- package/skills/ios/swift-security-expert/references/secure-enclave.md +539 -0
- package/skills/ios/swift-security-expert/references/testing-security-code.md +781 -0
- package/skills/ios/swift-testing-expert/LICENSE +21 -0
- package/skills/ios/swift-testing-expert/SKILL.md +79 -0
- package/skills/ios/swift-testing-expert/references/_index.md +12 -0
- package/skills/ios/swift-testing-expert/references/async-testing-and-waiting.md +127 -0
- package/skills/ios/swift-testing-expert/references/expectations.md +145 -0
- package/skills/ios/swift-testing-expert/references/fundamentals.md +141 -0
- package/skills/ios/swift-testing-expert/references/migration-from-xctest.md +127 -0
- package/skills/ios/swift-testing-expert/references/parallelization-and-isolation.md +95 -0
- package/skills/ios/swift-testing-expert/references/parameterized-testing.md +284 -0
- package/skills/ios/swift-testing-expert/references/performance-and-best-practices.md +187 -0
- package/skills/ios/swift-testing-expert/references/traits-and-tags.md +114 -0
- package/skills/ios/swift-testing-expert/references/xcode-workflows.md +70 -0
- package/skills/ios/swiftdata-pro/LICENSE +21 -0
- package/skills/ios/swiftdata-pro/SKILL.md +102 -0
- package/skills/ios/swiftdata-pro/agents/openai.yaml +10 -0
- package/skills/ios/swiftdata-pro/assets/swiftdata-pro-icon.png +0 -0
- package/skills/ios/swiftdata-pro/assets/swiftdata-pro-icon.svg +29 -0
- package/skills/ios/swiftdata-pro/references/class-inheritance.md +104 -0
- package/skills/ios/swiftdata-pro/references/cloudkit.md +10 -0
- package/skills/ios/swiftdata-pro/references/core-rules.md +20 -0
- package/skills/ios/swiftdata-pro/references/indexing.md +27 -0
- package/skills/ios/swiftdata-pro/references/predicates.md +73 -0
- package/skills/ios/swiftui-design-principles/AGENTS.md +21 -0
- package/skills/ios/swiftui-design-principles/LICENSE +21 -0
- package/skills/ios/swiftui-design-principles/README.md +41 -0
- package/skills/ios/swiftui-design-principles/SKILL.md +605 -0
- package/skills/ios/swiftui-design-principles/metadata.json +10 -0
- package/skills/ios/swiftui-liquid-glass/LICENSE +21 -0
- package/skills/ios/swiftui-liquid-glass/SKILL.md +95 -0
- package/skills/ios/swiftui-liquid-glass/agents/openai.yaml +4 -0
- package/skills/ios/swiftui-liquid-glass/references/liquid-glass.md +280 -0
- package/skills/ios/swiftui-performance-audit/LICENSE +21 -0
- package/skills/ios/swiftui-performance-audit/SKILL.md +111 -0
- package/skills/ios/swiftui-performance-audit/agents/openai.yaml +4 -0
- package/skills/ios/swiftui-performance-audit/references/code-smells.md +150 -0
- package/skills/ios/swiftui-performance-audit/references/demystify-swiftui-performance-wwdc23.md +46 -0
- package/skills/ios/swiftui-performance-audit/references/optimizing-swiftui-performance-instruments.md +29 -0
- package/skills/ios/swiftui-performance-audit/references/profiling-intake.md +44 -0
- package/skills/ios/swiftui-performance-audit/references/report-template.md +47 -0
- package/skills/ios/swiftui-performance-audit/references/understanding-hangs-in-your-app.md +33 -0
- package/skills/ios/swiftui-performance-audit/references/understanding-improving-swiftui-performance.md +52 -0
- package/skills/ios/swiftui-pro/LICENSE +21 -0
- package/skills/ios/swiftui-pro/SKILL.md +108 -0
- package/skills/ios/swiftui-pro/agents/openai.yaml +10 -0
- package/skills/ios/swiftui-pro/assets/swiftui-pro-icon.png +0 -0
- package/skills/ios/swiftui-pro/assets/swiftui-pro-icon.svg +29 -0
- package/skills/ios/swiftui-pro/references/accessibility.md +13 -0
- package/skills/ios/swiftui-pro/references/api.md +39 -0
- package/skills/ios/swiftui-pro/references/data.md +43 -0
- package/skills/ios/swiftui-pro/references/design.md +31 -0
- package/skills/ios/swiftui-pro/references/hygiene.md +9 -0
- package/skills/ios/swiftui-pro/references/navigation.md +14 -0
- package/skills/ios/swiftui-pro/references/performance.md +46 -0
- package/skills/ios/swiftui-pro/references/swift.md +56 -0
- package/skills/ios/swiftui-pro/references/views.md +35 -0
- package/skills/ios/swiftui-ui-patterns/LICENSE +21 -0
- package/skills/ios/swiftui-ui-patterns/SKILL.md +100 -0
- package/skills/ios/swiftui-ui-patterns/agents/openai.yaml +4 -0
- package/skills/ios/swiftui-ui-patterns/references/app-wiring.md +201 -0
- package/skills/ios/swiftui-ui-patterns/references/async-state.md +96 -0
- package/skills/ios/swiftui-ui-patterns/references/components-index.md +50 -0
- package/skills/ios/swiftui-ui-patterns/references/controls.md +57 -0
- package/skills/ios/swiftui-ui-patterns/references/deeplinks.md +66 -0
- package/skills/ios/swiftui-ui-patterns/references/focus.md +90 -0
- package/skills/ios/swiftui-ui-patterns/references/form.md +97 -0
- package/skills/ios/swiftui-ui-patterns/references/grids.md +71 -0
- package/skills/ios/swiftui-ui-patterns/references/haptics.md +71 -0
- package/skills/ios/swiftui-ui-patterns/references/input-toolbar.md +51 -0
- package/skills/ios/swiftui-ui-patterns/references/lightweight-clients.md +93 -0
- package/skills/ios/swiftui-ui-patterns/references/list.md +86 -0
- package/skills/ios/swiftui-ui-patterns/references/loading-placeholders.md +38 -0
- package/skills/ios/swiftui-ui-patterns/references/macos-settings.md +71 -0
- package/skills/ios/swiftui-ui-patterns/references/matched-transitions.md +59 -0
- package/skills/ios/swiftui-ui-patterns/references/media.md +73 -0
- package/skills/ios/swiftui-ui-patterns/references/menu-bar.md +101 -0
- package/skills/ios/swiftui-ui-patterns/references/navigationstack.md +159 -0
- package/skills/ios/swiftui-ui-patterns/references/overlay.md +45 -0
- package/skills/ios/swiftui-ui-patterns/references/performance.md +62 -0
- package/skills/ios/swiftui-ui-patterns/references/previews.md +48 -0
- package/skills/ios/swiftui-ui-patterns/references/scroll-reveal.md +133 -0
- package/skills/ios/swiftui-ui-patterns/references/scrollview.md +87 -0
- package/skills/ios/swiftui-ui-patterns/references/searchable.md +71 -0
- package/skills/ios/swiftui-ui-patterns/references/sheets.md +155 -0
- package/skills/ios/swiftui-ui-patterns/references/split-views.md +72 -0
- package/skills/ios/swiftui-ui-patterns/references/tabview.md +114 -0
- package/skills/ios/swiftui-ui-patterns/references/theming.md +71 -0
- package/skills/ios/swiftui-ui-patterns/references/title-menus.md +93 -0
- package/skills/ios/swiftui-ui-patterns/references/top-bar.md +49 -0
- package/skills/ios/swiftui-view-refactor/LICENSE +21 -0
- package/skills/ios/swiftui-view-refactor/SKILL.md +207 -0
- package/skills/ios/swiftui-view-refactor/agents/openai.yaml +4 -0
- package/skills/ios/swiftui-view-refactor/references/mv-patterns.md +161 -0
- package/skills/ios/widgetkit/LICENSE +131 -0
- package/skills/ios/widgetkit/SKILL.md +502 -0
- package/skills/ios/widgetkit/references/widgetkit-advanced.md +871 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Title menus
|
|
2
|
+
|
|
3
|
+
## Intent
|
|
4
|
+
|
|
5
|
+
Use a title menu in the navigation bar to provide context‑specific filtering or quick actions without adding extra chrome.
|
|
6
|
+
|
|
7
|
+
## Core patterns
|
|
8
|
+
|
|
9
|
+
- Use `ToolbarTitleMenu` to attach a menu to the navigation title.
|
|
10
|
+
- Keep the menu content compact and grouped with dividers.
|
|
11
|
+
|
|
12
|
+
## Example: title menu for filters
|
|
13
|
+
|
|
14
|
+
```swift
|
|
15
|
+
@ToolbarContentBuilder
|
|
16
|
+
private var toolbarView: some ToolbarContent {
|
|
17
|
+
ToolbarTitleMenu {
|
|
18
|
+
Button("Latest") { timeline = .latest }
|
|
19
|
+
Button("Resume") { timeline = .resume }
|
|
20
|
+
Divider()
|
|
21
|
+
Button("Local") { timeline = .local }
|
|
22
|
+
Button("Federated") { timeline = .federated }
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Example: attach to a view
|
|
28
|
+
|
|
29
|
+
```swift
|
|
30
|
+
NavigationStack {
|
|
31
|
+
TimelineView()
|
|
32
|
+
.toolbar {
|
|
33
|
+
toolbarView
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Example: title + menu together
|
|
39
|
+
|
|
40
|
+
```swift
|
|
41
|
+
struct TimelineScreen: View {
|
|
42
|
+
@State private var timeline: TimelineFilter = .home
|
|
43
|
+
|
|
44
|
+
var body: some View {
|
|
45
|
+
NavigationStack {
|
|
46
|
+
TimelineView()
|
|
47
|
+
.toolbar {
|
|
48
|
+
ToolbarItem(placement: .principal) {
|
|
49
|
+
VStack(spacing: 2) {
|
|
50
|
+
Text(timeline.title)
|
|
51
|
+
.font(.headline)
|
|
52
|
+
Text(timeline.subtitle)
|
|
53
|
+
.font(.caption)
|
|
54
|
+
.foregroundStyle(.secondary)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
ToolbarTitleMenu {
|
|
59
|
+
Button("Home") { timeline = .home }
|
|
60
|
+
Button("Local") { timeline = .local }
|
|
61
|
+
Button("Federated") { timeline = .federated }
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
.navigationBarTitleDisplayMode(.inline)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Example: title + subtitle with menu
|
|
71
|
+
|
|
72
|
+
```swift
|
|
73
|
+
ToolbarItem(placement: .principal) {
|
|
74
|
+
VStack(spacing: 2) {
|
|
75
|
+
Text(title)
|
|
76
|
+
.font(.headline)
|
|
77
|
+
Text(subtitle)
|
|
78
|
+
.font(.caption)
|
|
79
|
+
.foregroundStyle(.secondary)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Design choices to keep
|
|
85
|
+
|
|
86
|
+
- Only show the title menu when filtering or context switching is available.
|
|
87
|
+
- Keep the title readable; avoid long labels that truncate.
|
|
88
|
+
- Use secondary text below the title if extra context is needed.
|
|
89
|
+
|
|
90
|
+
## Pitfalls
|
|
91
|
+
|
|
92
|
+
- Don’t overload the menu with too many options.
|
|
93
|
+
- Avoid using title menus for destructive actions.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Top bar overlays (iOS 26+ and fallback)
|
|
2
|
+
|
|
3
|
+
## Intent
|
|
4
|
+
|
|
5
|
+
Provide a custom top selector or pill row that sits above scroll content, using `safeAreaBar(.top)` on iOS 26 and a compatible fallback on earlier OS versions.
|
|
6
|
+
|
|
7
|
+
## iOS 26+ approach
|
|
8
|
+
|
|
9
|
+
Use `safeAreaBar(edge: .top)` to attach the view to the safe area bar.
|
|
10
|
+
|
|
11
|
+
```swift
|
|
12
|
+
if #available(iOS 26.0, *) {
|
|
13
|
+
content
|
|
14
|
+
.safeAreaBar(edge: .top) {
|
|
15
|
+
TopSelectorView()
|
|
16
|
+
.padding(.horizontal, .layoutPadding)
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Fallback for earlier iOS
|
|
22
|
+
|
|
23
|
+
Use `.safeAreaInset(edge: .top)` and hide the toolbar background to avoid double layers.
|
|
24
|
+
|
|
25
|
+
```swift
|
|
26
|
+
content
|
|
27
|
+
.toolbarBackground(.hidden, for: .navigationBar)
|
|
28
|
+
.safeAreaInset(edge: .top, spacing: 0) {
|
|
29
|
+
VStack(spacing: 0) {
|
|
30
|
+
TopSelectorView()
|
|
31
|
+
.padding(.vertical, 8)
|
|
32
|
+
.padding(.horizontal, .layoutPadding)
|
|
33
|
+
.background(Color.primary.opacity(0.06))
|
|
34
|
+
.background(Material.ultraThin)
|
|
35
|
+
Divider()
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Design choices to keep
|
|
41
|
+
|
|
42
|
+
- Use `safeAreaBar` when available; it integrates better with the navigation bar.
|
|
43
|
+
- Use a subtle background + divider in the fallback to keep separation from content.
|
|
44
|
+
- Keep the selector height compact to avoid pushing content too far down.
|
|
45
|
+
|
|
46
|
+
## Pitfalls
|
|
47
|
+
|
|
48
|
+
- Don’t stack multiple top insets; it can create extra padding.
|
|
49
|
+
- Avoid heavy, opaque backgrounds that fight the navigation bar.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Thomas Ricouard
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: swiftui-view-refactor
|
|
3
|
+
description: Refactor and review SwiftUI view files with strong defaults for small dedicated subviews, MV-over-MVVM data flow, stable view trees, explicit dependency injection, and correct Observation usage. Use when cleaning up a SwiftUI view, splitting long bodies, removing inline actions or side effects, reducing computed `some View` helpers, or standardizing `@Observable` and view model initialization patterns.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SwiftUI View Refactor
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
Refactor SwiftUI views toward small, explicit, stable view types. Default to vanilla SwiftUI: local state in the view, shared dependencies in the environment, business logic in services/models, and view models only when the request or existing code clearly requires one.
|
|
10
|
+
|
|
11
|
+
## Core Guidelines
|
|
12
|
+
|
|
13
|
+
### 1) View ordering (top → bottom)
|
|
14
|
+
- Enforce this ordering unless the existing file has a stronger local convention you must preserve.
|
|
15
|
+
- Environment
|
|
16
|
+
- `private`/`public` `let`
|
|
17
|
+
- `@State` / other stored properties
|
|
18
|
+
- computed `var` (non-view)
|
|
19
|
+
- `init`
|
|
20
|
+
- `body`
|
|
21
|
+
- computed view builders / other view helpers
|
|
22
|
+
- helper / async functions
|
|
23
|
+
|
|
24
|
+
### 2) Default to MV, not MVVM
|
|
25
|
+
- Views should be lightweight state expressions and orchestration points, not containers for business logic.
|
|
26
|
+
- Favor `@State`, `@Environment`, `@Query`, `.task`, `.task(id:)`, and `onChange` before reaching for a view model.
|
|
27
|
+
- Inject services and shared models via `@Environment`; keep domain logic in services/models, not in the view body.
|
|
28
|
+
- Do not introduce a view model just to mirror local view state or wrap environment dependencies.
|
|
29
|
+
- If a screen is getting large, split the UI into subviews before inventing a new view model layer.
|
|
30
|
+
|
|
31
|
+
### 3) Strongly prefer dedicated subview types over computed `some View` helpers
|
|
32
|
+
- Flag `body` properties that are longer than roughly one screen or contain multiple logical sections.
|
|
33
|
+
- Prefer extracting dedicated `View` types for non-trivial sections, especially when they have state, async work, branching, or deserve their own preview.
|
|
34
|
+
- Keep computed `some View` helpers rare and small. Do not build an entire screen out of `private var header: some View`-style fragments.
|
|
35
|
+
- Pass small, explicit inputs (data, bindings, callbacks) into extracted subviews instead of handing down the entire parent state.
|
|
36
|
+
- If an extracted subview becomes reusable or independently meaningful, move it to its own file.
|
|
37
|
+
|
|
38
|
+
Prefer:
|
|
39
|
+
|
|
40
|
+
```swift
|
|
41
|
+
var body: some View {
|
|
42
|
+
List {
|
|
43
|
+
HeaderSection(title: title, subtitle: subtitle)
|
|
44
|
+
FilterSection(
|
|
45
|
+
filterOptions: filterOptions,
|
|
46
|
+
selectedFilter: $selectedFilter
|
|
47
|
+
)
|
|
48
|
+
ResultsSection(items: filteredItems)
|
|
49
|
+
FooterSection()
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
private struct HeaderSection: View {
|
|
54
|
+
let title: String
|
|
55
|
+
let subtitle: String
|
|
56
|
+
|
|
57
|
+
var body: some View {
|
|
58
|
+
VStack(alignment: .leading, spacing: 6) {
|
|
59
|
+
Text(title).font(.title2)
|
|
60
|
+
Text(subtitle).font(.subheadline)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
private struct FilterSection: View {
|
|
66
|
+
let filterOptions: [FilterOption]
|
|
67
|
+
@Binding var selectedFilter: FilterOption
|
|
68
|
+
|
|
69
|
+
var body: some View {
|
|
70
|
+
ScrollView(.horizontal, showsIndicators: false) {
|
|
71
|
+
HStack {
|
|
72
|
+
ForEach(filterOptions, id: \.self) { option in
|
|
73
|
+
FilterChip(option: option, isSelected: option == selectedFilter)
|
|
74
|
+
.onTapGesture { selectedFilter = option }
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Avoid:
|
|
83
|
+
|
|
84
|
+
```swift
|
|
85
|
+
var body: some View {
|
|
86
|
+
List {
|
|
87
|
+
header
|
|
88
|
+
filters
|
|
89
|
+
results
|
|
90
|
+
footer
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
private var header: some View {
|
|
95
|
+
VStack(alignment: .leading, spacing: 6) {
|
|
96
|
+
Text(title).font(.title2)
|
|
97
|
+
Text(subtitle).font(.subheadline)
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### 3b) Extract actions and side effects out of `body`
|
|
103
|
+
- Do not keep non-trivial button actions inline in the view body.
|
|
104
|
+
- Do not bury business logic inside `.task`, `.onAppear`, `.onChange`, or `.refreshable`.
|
|
105
|
+
- Prefer calling small private methods from the view, and move real business logic into services/models.
|
|
106
|
+
- The body should read like UI, not like a view controller.
|
|
107
|
+
|
|
108
|
+
```swift
|
|
109
|
+
Button("Save", action: save)
|
|
110
|
+
.disabled(isSaving)
|
|
111
|
+
|
|
112
|
+
.task(id: searchText) {
|
|
113
|
+
await reload(for: searchText)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
private func save() {
|
|
117
|
+
Task { await saveAsync() }
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
private func reload(for searchText: String) async {
|
|
121
|
+
guard !searchText.isEmpty else {
|
|
122
|
+
results = []
|
|
123
|
+
return
|
|
124
|
+
}
|
|
125
|
+
await searchService.search(searchText)
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### 4) Keep a stable view tree (avoid top-level conditional view swapping)
|
|
130
|
+
- Avoid `body` or computed views that return completely different root branches via `if/else`.
|
|
131
|
+
- Prefer a single stable base view with conditions inside sections/modifiers (`overlay`, `opacity`, `disabled`, `toolbar`, etc.).
|
|
132
|
+
- Root-level branch swapping causes identity churn, broader invalidation, and extra recomputation.
|
|
133
|
+
|
|
134
|
+
Prefer:
|
|
135
|
+
|
|
136
|
+
```swift
|
|
137
|
+
var body: some View {
|
|
138
|
+
List {
|
|
139
|
+
documentsListContent
|
|
140
|
+
}
|
|
141
|
+
.toolbar {
|
|
142
|
+
if canEdit {
|
|
143
|
+
editToolbar
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Avoid:
|
|
150
|
+
|
|
151
|
+
```swift
|
|
152
|
+
var documentsListView: some View {
|
|
153
|
+
if canEdit {
|
|
154
|
+
editableDocumentsList
|
|
155
|
+
} else {
|
|
156
|
+
readOnlyDocumentsList
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### 5) View model handling (only if already present or explicitly requested)
|
|
162
|
+
- Treat view models as a legacy or explicit-need pattern, not the default.
|
|
163
|
+
- Do not introduce a view model unless the request or existing code clearly calls for one.
|
|
164
|
+
- If a view model exists, make it non-optional when possible.
|
|
165
|
+
- Pass dependencies to the view via `init`, then create the view model in the view's `init`.
|
|
166
|
+
- Avoid `bootstrapIfNeeded` patterns and other delayed setup workarounds.
|
|
167
|
+
|
|
168
|
+
Example (Observation-based):
|
|
169
|
+
|
|
170
|
+
```swift
|
|
171
|
+
@State private var viewModel: SomeViewModel
|
|
172
|
+
|
|
173
|
+
init(dependency: Dependency) {
|
|
174
|
+
_viewModel = State(initialValue: SomeViewModel(dependency: dependency))
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### 6) Observation usage
|
|
179
|
+
- For `@Observable` reference types on iOS 17+, store them as `@State` in the owning view.
|
|
180
|
+
- Pass observables down explicitly; avoid optional state unless the UI genuinely needs it.
|
|
181
|
+
- If the deployment target includes iOS 16 or earlier, use `@StateObject` at the owner and `@ObservedObject` when injecting legacy observable models.
|
|
182
|
+
|
|
183
|
+
## Workflow
|
|
184
|
+
|
|
185
|
+
1. Reorder the view to match the ordering rules.
|
|
186
|
+
2. Remove inline actions and side effects from `body`; move business logic into services/models and keep only thin orchestration in the view.
|
|
187
|
+
3. Shorten long bodies by extracting dedicated subview types; avoid rebuilding the screen out of many computed `some View` helpers.
|
|
188
|
+
4. Ensure stable view structure: avoid top-level `if`-based branch swapping; move conditions to localized sections/modifiers.
|
|
189
|
+
5. If a view model exists or is explicitly required, replace optional view models with a non-optional `@State` view model initialized in `init`.
|
|
190
|
+
6. Confirm Observation usage: `@State` for root `@Observable` models on iOS 17+, legacy wrappers only when the deployment target requires them.
|
|
191
|
+
7. Keep behavior intact: do not change layout or business logic unless requested.
|
|
192
|
+
|
|
193
|
+
## Notes
|
|
194
|
+
|
|
195
|
+
- Prefer small, explicit view types over large conditional blocks and large computed `some View` properties.
|
|
196
|
+
- Keep computed view builders below `body` and non-view computed vars above `init`.
|
|
197
|
+
- A good SwiftUI refactor should make the view read top-to-bottom as data flow plus layout, not as mixed layout and imperative logic.
|
|
198
|
+
- For MV-first guidance and rationale, see `references/mv-patterns.md`.
|
|
199
|
+
|
|
200
|
+
## Large-view handling
|
|
201
|
+
|
|
202
|
+
When a SwiftUI view file exceeds ~300 lines, split it aggressively. Extract meaningful sections into dedicated `View` types instead of hiding complexity in many computed properties. Use `private` extensions with `// MARK: -` comments for actions and helpers, but do not treat extensions as a substitute for breaking a giant screen into smaller view types. If an extracted subview is reused or independently meaningful, move it into its own file.
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
Vendored from: https://github.com/Dimillian/Skills/tree/main/swiftui-view-refactor
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# MV Patterns Reference
|
|
2
|
+
|
|
3
|
+
Distilled guidance for deciding whether a SwiftUI feature should stay as plain MV or introduce a view model.
|
|
4
|
+
|
|
5
|
+
Inspired by the user's provided source, "SwiftUI in 2025: Forget MVVM" (Thomas Ricouard), but rewritten here as a practical refactoring reference.
|
|
6
|
+
|
|
7
|
+
## Default stance
|
|
8
|
+
|
|
9
|
+
- Default to MV: views are lightweight state expressions and orchestration points.
|
|
10
|
+
- Prefer `@State`, `@Environment`, `@Query`, `.task`, `.task(id:)`, and `onChange` before reaching for a view model.
|
|
11
|
+
- Keep business logic in services, models, or domain types, not in the view body.
|
|
12
|
+
- Split large screens into smaller view types before inventing a view model layer.
|
|
13
|
+
- Avoid manual fetching or state plumbing that duplicates SwiftUI or SwiftData mechanisms.
|
|
14
|
+
- Test services, models, and transformations first; views should stay simple and declarative.
|
|
15
|
+
|
|
16
|
+
## When to avoid a view model
|
|
17
|
+
|
|
18
|
+
Do not introduce a view model when it would mostly:
|
|
19
|
+
- mirror local view state,
|
|
20
|
+
- wrap values already available through `@Environment`,
|
|
21
|
+
- duplicate `@Query`, `@State`, or `Binding`-based data flow,
|
|
22
|
+
- exist only because the view body is too long,
|
|
23
|
+
- hold one-off async loading logic that can live in `.task` plus local view state.
|
|
24
|
+
|
|
25
|
+
In these cases, simplify the view and data flow instead of adding indirection.
|
|
26
|
+
|
|
27
|
+
## When a view model may be justified
|
|
28
|
+
|
|
29
|
+
A view model can be reasonable when at least one of these is true:
|
|
30
|
+
- the user explicitly asks for one,
|
|
31
|
+
- the codebase already standardizes on a view model pattern for that feature,
|
|
32
|
+
- the screen needs a long-lived reference model with behavior that does not fit naturally in services alone,
|
|
33
|
+
- the feature is adapting a non-SwiftUI API that needs a dedicated bridge object,
|
|
34
|
+
- multiple views share the same presentation-specific state and that state is not better modeled as app-level environment data.
|
|
35
|
+
|
|
36
|
+
Even then, keep the view model small, explicit, and non-optional when possible.
|
|
37
|
+
|
|
38
|
+
## Preferred pattern: local state plus environment
|
|
39
|
+
|
|
40
|
+
```swift
|
|
41
|
+
struct FeedView: View {
|
|
42
|
+
@Environment(BlueSkyClient.self) private var client
|
|
43
|
+
|
|
44
|
+
enum ViewState {
|
|
45
|
+
case loading
|
|
46
|
+
case error(String)
|
|
47
|
+
case loaded([Post])
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@State private var viewState: ViewState = .loading
|
|
51
|
+
|
|
52
|
+
var body: some View {
|
|
53
|
+
List {
|
|
54
|
+
switch viewState {
|
|
55
|
+
case .loading:
|
|
56
|
+
ProgressView("Loading feed...")
|
|
57
|
+
case .error(let message):
|
|
58
|
+
ErrorStateView(message: message, retryAction: { await loadFeed() })
|
|
59
|
+
case .loaded(let posts):
|
|
60
|
+
ForEach(posts) { post in
|
|
61
|
+
PostRowView(post: post)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
.task { await loadFeed() }
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
private func loadFeed() async {
|
|
69
|
+
do {
|
|
70
|
+
let posts = try await client.getFeed()
|
|
71
|
+
viewState = .loaded(posts)
|
|
72
|
+
} catch {
|
|
73
|
+
viewState = .error(error.localizedDescription)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Why this is preferred:
|
|
80
|
+
- state stays close to the UI that renders it,
|
|
81
|
+
- dependencies come from the environment instead of a wrapper object,
|
|
82
|
+
- the view coordinates UI flow while the service owns the real work.
|
|
83
|
+
|
|
84
|
+
## Preferred pattern: use modifiers as lightweight orchestration
|
|
85
|
+
|
|
86
|
+
```swift
|
|
87
|
+
.task(id: searchText) {
|
|
88
|
+
guard !searchText.isEmpty else {
|
|
89
|
+
results = []
|
|
90
|
+
return
|
|
91
|
+
}
|
|
92
|
+
await searchFeed(query: searchText)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.onChange(of: isInSearch, initial: false) {
|
|
96
|
+
guard !isInSearch else { return }
|
|
97
|
+
Task { await fetchSuggestedFeed() }
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Use view lifecycle modifiers for simple, local orchestration. Do not convert these into a view model by default unless the behavior clearly outgrows the view.
|
|
102
|
+
|
|
103
|
+
## SwiftData note
|
|
104
|
+
|
|
105
|
+
SwiftData is a strong argument for keeping data flow inside the view when possible.
|
|
106
|
+
|
|
107
|
+
Prefer:
|
|
108
|
+
|
|
109
|
+
```swift
|
|
110
|
+
struct BookListView: View {
|
|
111
|
+
@Query private var books: [Book]
|
|
112
|
+
@Environment(\.modelContext) private var modelContext
|
|
113
|
+
|
|
114
|
+
var body: some View {
|
|
115
|
+
List {
|
|
116
|
+
ForEach(books) { book in
|
|
117
|
+
BookRowView(book: book)
|
|
118
|
+
.swipeActions {
|
|
119
|
+
Button("Delete", role: .destructive) {
|
|
120
|
+
modelContext.delete(book)
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Avoid adding a view model that manually fetches and mirrors the same state unless the feature has an explicit reason to do so.
|
|
130
|
+
|
|
131
|
+
## Testing guidance
|
|
132
|
+
|
|
133
|
+
Prefer to test:
|
|
134
|
+
- services and business rules,
|
|
135
|
+
- models and state transformations,
|
|
136
|
+
- async workflows at the service layer,
|
|
137
|
+
- UI behavior with previews or higher-level UI tests.
|
|
138
|
+
|
|
139
|
+
Do not introduce a view model primarily to make a simple SwiftUI view "testable." That usually adds ceremony without improving the architecture.
|
|
140
|
+
|
|
141
|
+
## Refactor checklist
|
|
142
|
+
|
|
143
|
+
When refactoring toward MV:
|
|
144
|
+
- Remove view models that only wrap environment dependencies or local view state.
|
|
145
|
+
- Replace optional or delayed-initialized view models when plain view state is enough.
|
|
146
|
+
- Pull business logic out of the view body and into services/models.
|
|
147
|
+
- Keep the view as a thin coordinator of UI state, navigation, and user actions.
|
|
148
|
+
- Split large bodies into smaller view types before adding new layers of indirection.
|
|
149
|
+
|
|
150
|
+
## Bottom line
|
|
151
|
+
|
|
152
|
+
Treat view models as the exception, not the default.
|
|
153
|
+
|
|
154
|
+
In modern SwiftUI, the default stack is:
|
|
155
|
+
- `@State` for local state,
|
|
156
|
+
- `@Environment` for shared dependencies,
|
|
157
|
+
- `@Query` for SwiftData-backed collections,
|
|
158
|
+
- lifecycle modifiers for lightweight orchestration,
|
|
159
|
+
- services and models for business logic.
|
|
160
|
+
|
|
161
|
+
Reach for a view model only when the feature clearly needs one.
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
Required Notice: Copyright (c) 2025 dpearson2699 (https://github.com/dpearson2699)
|
|
2
|
+
|
|
3
|
+
# PolyForm Perimeter License 1.0.0
|
|
4
|
+
|
|
5
|
+
<https://polyformproject.org/licenses/perimeter/1.0.0>
|
|
6
|
+
|
|
7
|
+
## Acceptance
|
|
8
|
+
|
|
9
|
+
In order to get any license under these terms, you must agree
|
|
10
|
+
to them as both strict obligations and conditions to all
|
|
11
|
+
your licenses.
|
|
12
|
+
|
|
13
|
+
## Copyright License
|
|
14
|
+
|
|
15
|
+
The licensor grants you a copyright license for the
|
|
16
|
+
software to do everything you might do with the software
|
|
17
|
+
that would otherwise infringe the licensor's copyright
|
|
18
|
+
in it for any permitted purpose. However, you may
|
|
19
|
+
only distribute the software according to [Distribution
|
|
20
|
+
License](#distribution-license) and make changes or new works
|
|
21
|
+
based on the software according to [Changes and New Works
|
|
22
|
+
License](#changes-and-new-works-license).
|
|
23
|
+
|
|
24
|
+
## Distribution License
|
|
25
|
+
|
|
26
|
+
The licensor grants you an additional copyright license
|
|
27
|
+
to distribute copies of the software. Your license
|
|
28
|
+
to distribute covers distributing the software with
|
|
29
|
+
changes and new works permitted by [Changes and New Works
|
|
30
|
+
License](#changes-and-new-works-license).
|
|
31
|
+
|
|
32
|
+
## Notices
|
|
33
|
+
|
|
34
|
+
You must ensure that anyone who gets a copy of any part of
|
|
35
|
+
the software from you also gets a copy of these terms or the
|
|
36
|
+
URL for them above, as well as copies of any plain-text lines
|
|
37
|
+
beginning with `Required Notice:` that the licensor provided
|
|
38
|
+
with the software. For example:
|
|
39
|
+
|
|
40
|
+
> Required Notice: Copyright Yoyodyne, Inc. (http://example.com)
|
|
41
|
+
|
|
42
|
+
## Changes and New Works License
|
|
43
|
+
|
|
44
|
+
The licensor grants you an additional copyright license to
|
|
45
|
+
make changes and new works based on the software for any
|
|
46
|
+
permitted purpose.
|
|
47
|
+
|
|
48
|
+
## Patent License
|
|
49
|
+
|
|
50
|
+
The licensor grants you a patent license for the software that
|
|
51
|
+
covers patent claims the licensor can license, or becomes able
|
|
52
|
+
to license, that you would infringe by using the software.
|
|
53
|
+
|
|
54
|
+
## Noncompete
|
|
55
|
+
|
|
56
|
+
Any purpose is a permitted purpose, except for providing to
|
|
57
|
+
others any product that competes with the software.
|
|
58
|
+
|
|
59
|
+
## Competition
|
|
60
|
+
|
|
61
|
+
If you use this software to market a product as a substitute
|
|
62
|
+
for the functionality or value of the software, it competes
|
|
63
|
+
with the software. A product may compete regardless how it is
|
|
64
|
+
designed or deployed. For example, a product may compete even
|
|
65
|
+
if it provides its functionality via any kind of interface
|
|
66
|
+
(including services, libraries or plug-ins), even if it is
|
|
67
|
+
ported to a different platforms or programming languages,
|
|
68
|
+
and even if it is provided free of charge.
|
|
69
|
+
|
|
70
|
+
## Fair Use
|
|
71
|
+
|
|
72
|
+
You may have "fair use" rights for the software under the
|
|
73
|
+
law. These terms do not limit them.
|
|
74
|
+
|
|
75
|
+
## No Other Rights
|
|
76
|
+
|
|
77
|
+
These terms do not allow you to sublicense or transfer any of
|
|
78
|
+
your licenses to anyone else, or prevent the licensor from
|
|
79
|
+
granting licenses to anyone else. These terms do not imply
|
|
80
|
+
any other licenses.
|
|
81
|
+
|
|
82
|
+
## Patent Defense
|
|
83
|
+
|
|
84
|
+
If you make any written claim that the software infringes or
|
|
85
|
+
contributes to infringement of any patent, your patent license
|
|
86
|
+
for the software granted under these terms ends immediately. If
|
|
87
|
+
your company makes such a claim, your patent license ends
|
|
88
|
+
immediately for work on behalf of your company.
|
|
89
|
+
|
|
90
|
+
## Violations
|
|
91
|
+
|
|
92
|
+
The first time you are notified in writing that you have
|
|
93
|
+
violated any of these terms, or done anything with the software
|
|
94
|
+
not covered by your licenses, your licenses can nonetheless
|
|
95
|
+
continue if you come into full compliance with these terms,
|
|
96
|
+
and take practical steps to correct past violations, within
|
|
97
|
+
32 days of receiving notice. Otherwise, all your licenses
|
|
98
|
+
end immediately.
|
|
99
|
+
|
|
100
|
+
## No Liability
|
|
101
|
+
|
|
102
|
+
***As far as the law allows, the software comes as is, without
|
|
103
|
+
any warranty or condition, and the licensor will not be liable
|
|
104
|
+
to you for any damages arising out of these terms or the use
|
|
105
|
+
or nature of the software, under any kind of legal claim.***
|
|
106
|
+
|
|
107
|
+
## Definitions
|
|
108
|
+
|
|
109
|
+
The **licensor** is the individual or entity offering these
|
|
110
|
+
terms, and the **software** is the software the licensor makes
|
|
111
|
+
available under these terms.
|
|
112
|
+
|
|
113
|
+
A **product** can be a good or service, or a combination
|
|
114
|
+
of them.
|
|
115
|
+
|
|
116
|
+
**You** refers to the individual or entity agreeing to these
|
|
117
|
+
terms.
|
|
118
|
+
|
|
119
|
+
**Your company** is any legal entity, sole proprietorship,
|
|
120
|
+
or other kind of organization that you work for, plus all
|
|
121
|
+
organizations that have control over, are under the control of,
|
|
122
|
+
or are under common control with that organization. **Control**
|
|
123
|
+
means ownership of substantially all the assets of an entity,
|
|
124
|
+
or the power to direct its management and policies by vote,
|
|
125
|
+
contract, or otherwise. Control can be direct or indirect.
|
|
126
|
+
|
|
127
|
+
**Your licenses** are all the licenses granted to you for the
|
|
128
|
+
software under these terms.
|
|
129
|
+
|
|
130
|
+
**Use** means anything you do with the software requiring one
|
|
131
|
+
of your licenses.
|