claude-code-pilot 3.1.0 → 3.2.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/README.md +11 -11
- package/bin/install.js +20 -2
- package/manifest.json +5 -1
- package/package.json +18 -6
- package/src/agents/a11y-architect.md +141 -0
- package/src/agents/code-architect.md +71 -0
- package/src/agents/code-explorer.md +69 -0
- package/src/agents/code-simplifier.md +47 -0
- package/src/agents/comment-analyzer.md +45 -0
- package/src/agents/csharp-reviewer.md +101 -0
- package/src/agents/dart-build-resolver.md +201 -0
- package/src/agents/pr-test-analyzer.md +45 -0
- package/src/agents/silent-failure-hunter.md +50 -0
- package/src/agents/type-design-analyzer.md +41 -0
- package/src/available-rules/README.md +3 -1
- package/src/available-rules/dart/coding-style.md +159 -0
- package/src/available-rules/dart/hooks.md +66 -0
- package/src/available-rules/dart/patterns.md +261 -0
- package/src/available-rules/dart/security.md +135 -0
- package/src/available-rules/dart/testing.md +215 -0
- package/src/available-rules/web/coding-style.md +105 -0
- package/src/available-rules/web/design-quality.md +72 -0
- package/src/available-rules/web/hooks.md +129 -0
- package/src/available-rules/web/patterns.md +88 -0
- package/src/available-rules/web/performance.md +73 -0
- package/src/available-rules/web/security.md +66 -0
- package/src/available-rules/web/testing.md +64 -0
- package/src/commands/ccp/ai-integration-phase.md +36 -0
- package/src/commands/ccp/audit-fix.md +33 -0
- package/src/commands/ccp/code-review-fix.md +52 -0
- package/src/commands/ccp/eval-review.md +32 -0
- package/src/commands/ccp/extract_learnings.md +22 -0
- package/src/commands/ccp/import.md +37 -0
- package/src/commands/ccp/ingest-docs.md +42 -0
- package/src/commands/ccp/intel.md +179 -0
- package/src/commands/ccp/plan-review-convergence.md +58 -0
- package/src/commands/ccp/scan.md +26 -0
- package/src/commands/ccp/sketch-wrap-up.md +31 -0
- package/src/commands/ccp/sketch.md +54 -0
- package/src/commands/ccp/spec-phase.md +62 -0
- package/src/commands/ccp/spike-wrap-up.md +31 -0
- package/src/commands/ccp/spike.md +51 -0
- package/src/commands/ccp/ultraplan-phase.md +33 -0
- package/src/hooks/ccp-read-injection-scanner.js +152 -0
- package/src/hooks/kit-check-update.js +59 -7
- package/src/hooks/run-with-flags-shell.sh +1 -0
- package/src/hooks/run-with-flags.js +48 -1
- package/src/hooks/session-end.js +88 -1
- package/src/lib/hook-flags.js +14 -0
- package/src/pilot/references/agent-contracts.md +79 -0
- package/src/pilot/references/ai-evals.md +156 -0
- package/src/pilot/references/ai-frameworks.md +186 -0
- package/src/pilot/references/doc-conflict-engine.md +91 -0
- package/src/pilot/references/gate-prompts.md +100 -0
- package/src/pilot/references/gates.md +70 -0
- package/src/pilot/references/mandatory-initial-read.md +2 -0
- package/src/pilot/references/project-skills-discovery.md +19 -0
- package/src/pilot/references/revision-loop.md +97 -0
- package/src/pilot/references/sketch-interactivity.md +41 -0
- package/src/pilot/references/sketch-theme-system.md +94 -0
- package/src/pilot/references/sketch-tooling.md +45 -0
- package/src/pilot/references/sketch-variant-patterns.md +81 -0
- package/src/pilot/references/thinking-models-debug.md +44 -0
- package/src/pilot/references/thinking-models-execution.md +50 -0
- package/src/pilot/references/thinking-models-planning.md +62 -0
- package/src/pilot/references/thinking-models-research.md +50 -0
- package/src/pilot/references/thinking-models-verification.md +55 -0
- package/src/pilot/templates/AI-SPEC.md +246 -0
- package/src/pilot/templates/spec.md +307 -0
- package/src/pilot/workflows/ai-integration-phase.md +284 -0
- package/src/pilot/workflows/audit-fix.md +175 -0
- package/src/pilot/workflows/code-review-fix.md +497 -0
- package/src/pilot/workflows/eval-review.md +155 -0
- package/src/pilot/workflows/extract_learnings.md +242 -0
- package/src/pilot/workflows/import.md +246 -0
- package/src/pilot/workflows/ingest-docs.md +328 -0
- package/src/pilot/workflows/plan-review-convergence.md +329 -0
- package/src/pilot/workflows/scan.md +102 -0
- package/src/pilot/workflows/sketch-wrap-up.md +285 -0
- package/src/pilot/workflows/sketch.md +360 -0
- package/src/pilot/workflows/spec-phase.md +262 -0
- package/src/pilot/workflows/spike-wrap-up.md +306 -0
- package/src/pilot/workflows/spike.md +452 -0
- package/src/pilot/workflows/ultraplan-phase.md +189 -0
- package/src/skills/accessibility/SKILL.md +146 -0
- package/src/skills/agent-eval/SKILL.md +145 -0
- package/src/skills/agent-introspection-debugging/SKILL.md +153 -0
- package/src/skills/android-clean-architecture/SKILL.md +339 -0
- package/src/skills/api-connector-builder/SKILL.md +120 -0
- package/src/skills/code-tour/SKILL.md +236 -0
- package/src/skills/compose-multiplatform-patterns/SKILL.md +299 -0
- package/src/skills/csharp-testing/SKILL.md +321 -0
- package/src/skills/dart-flutter-patterns/SKILL.md +563 -0
- package/src/skills/dashboard-builder/SKILL.md +108 -0
- package/src/skills/dotnet-patterns/SKILL.md +321 -0
- package/src/skills/frontend-design/SKILL.md +145 -0
- package/src/skills/frontend-slides/SKILL.md +184 -0
- package/src/skills/frontend-slides/STYLE_PRESETS.md +330 -0
- package/src/skills/gateguard/SKILL.md +121 -0
- package/src/skills/github-ops/SKILL.md +144 -0
- package/src/skills/hookify-rules/SKILL.md +128 -0
- package/src/skills/knowledge-ops/SKILL.md +154 -0
- package/src/skills/liquid-glass-design/SKILL.md +279 -0
- package/src/skills/nestjs-patterns/SKILL.md +230 -0
- package/src/skills/security-bounty-hunter/SKILL.md +99 -0
- package/src/skills/swift-actor-persistence/SKILL.md +143 -0
- package/src/skills/swift-protocol-di-testing/SKILL.md +190 -0
- package/src/skills/swiftui-patterns/SKILL.md +259 -0
- package/src/skills/terminal-ops/SKILL.md +109 -0
- package/src/skills/ui-demo/SKILL.md +465 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: swiftui-patterns
|
|
3
|
+
description: SwiftUI architecture patterns, state management with @Observable, view composition, navigation, performance optimization, and modern iOS/macOS UI best practices.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SwiftUI Patterns
|
|
7
|
+
|
|
8
|
+
Modern SwiftUI patterns for building declarative, performant user interfaces on Apple platforms. Covers the Observation framework, view composition, type-safe navigation, and performance optimization.
|
|
9
|
+
|
|
10
|
+
## When to Activate
|
|
11
|
+
|
|
12
|
+
- Building SwiftUI views and managing state (`@State`, `@Observable`, `@Binding`)
|
|
13
|
+
- Designing navigation flows with `NavigationStack`
|
|
14
|
+
- Structuring view models and data flow
|
|
15
|
+
- Optimizing rendering performance for lists and complex layouts
|
|
16
|
+
- Working with environment values and dependency injection in SwiftUI
|
|
17
|
+
|
|
18
|
+
## State Management
|
|
19
|
+
|
|
20
|
+
### Property Wrapper Selection
|
|
21
|
+
|
|
22
|
+
Choose the simplest wrapper that fits:
|
|
23
|
+
|
|
24
|
+
| Wrapper | Use Case |
|
|
25
|
+
|---------|----------|
|
|
26
|
+
| `@State` | View-local value types (toggles, form fields, sheet presentation) |
|
|
27
|
+
| `@Binding` | Two-way reference to parent's `@State` |
|
|
28
|
+
| `@Observable` class + `@State` | Owned model with multiple properties |
|
|
29
|
+
| `@Observable` class (no wrapper) | Read-only reference passed from parent |
|
|
30
|
+
| `@Bindable` | Two-way binding to an `@Observable` property |
|
|
31
|
+
| `@Environment` | Shared dependencies injected via `.environment()` |
|
|
32
|
+
|
|
33
|
+
### @Observable ViewModel
|
|
34
|
+
|
|
35
|
+
Use `@Observable` (not `ObservableObject`) — it tracks property-level changes so SwiftUI only re-renders views that read the changed property:
|
|
36
|
+
|
|
37
|
+
```swift
|
|
38
|
+
@Observable
|
|
39
|
+
final class ItemListViewModel {
|
|
40
|
+
private(set) var items: [Item] = []
|
|
41
|
+
private(set) var isLoading = false
|
|
42
|
+
var searchText = ""
|
|
43
|
+
|
|
44
|
+
private let repository: any ItemRepository
|
|
45
|
+
|
|
46
|
+
init(repository: any ItemRepository = DefaultItemRepository()) {
|
|
47
|
+
self.repository = repository
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
func load() async {
|
|
51
|
+
isLoading = true
|
|
52
|
+
defer { isLoading = false }
|
|
53
|
+
items = (try? await repository.fetchAll()) ?? []
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### View Consuming the ViewModel
|
|
59
|
+
|
|
60
|
+
```swift
|
|
61
|
+
struct ItemListView: View {
|
|
62
|
+
@State private var viewModel: ItemListViewModel
|
|
63
|
+
|
|
64
|
+
init(viewModel: ItemListViewModel = ItemListViewModel()) {
|
|
65
|
+
_viewModel = State(initialValue: viewModel)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
var body: some View {
|
|
69
|
+
List(viewModel.items) { item in
|
|
70
|
+
ItemRow(item: item)
|
|
71
|
+
}
|
|
72
|
+
.searchable(text: $viewModel.searchText)
|
|
73
|
+
.overlay { if viewModel.isLoading { ProgressView() } }
|
|
74
|
+
.task { await viewModel.load() }
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Environment Injection
|
|
80
|
+
|
|
81
|
+
Replace `@EnvironmentObject` with `@Environment`:
|
|
82
|
+
|
|
83
|
+
```swift
|
|
84
|
+
// Inject
|
|
85
|
+
ContentView()
|
|
86
|
+
.environment(authManager)
|
|
87
|
+
|
|
88
|
+
// Consume
|
|
89
|
+
struct ProfileView: View {
|
|
90
|
+
@Environment(AuthManager.self) private var auth
|
|
91
|
+
|
|
92
|
+
var body: some View {
|
|
93
|
+
Text(auth.currentUser?.name ?? "Guest")
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## View Composition
|
|
99
|
+
|
|
100
|
+
### Extract Subviews to Limit Invalidation
|
|
101
|
+
|
|
102
|
+
Break views into small, focused structs. When state changes, only the subview reading that state re-renders:
|
|
103
|
+
|
|
104
|
+
```swift
|
|
105
|
+
struct OrderView: View {
|
|
106
|
+
@State private var viewModel = OrderViewModel()
|
|
107
|
+
|
|
108
|
+
var body: some View {
|
|
109
|
+
VStack {
|
|
110
|
+
OrderHeader(title: viewModel.title)
|
|
111
|
+
OrderItemList(items: viewModel.items)
|
|
112
|
+
OrderTotal(total: viewModel.total)
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### ViewModifier for Reusable Styling
|
|
119
|
+
|
|
120
|
+
```swift
|
|
121
|
+
struct CardModifier: ViewModifier {
|
|
122
|
+
func body(content: Content) -> some View {
|
|
123
|
+
content
|
|
124
|
+
.padding()
|
|
125
|
+
.background(.regularMaterial)
|
|
126
|
+
.clipShape(RoundedRectangle(cornerRadius: 12))
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
extension View {
|
|
131
|
+
func cardStyle() -> some View {
|
|
132
|
+
modifier(CardModifier())
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Navigation
|
|
138
|
+
|
|
139
|
+
### Type-Safe NavigationStack
|
|
140
|
+
|
|
141
|
+
Use `NavigationStack` with `NavigationPath` for programmatic, type-safe routing:
|
|
142
|
+
|
|
143
|
+
```swift
|
|
144
|
+
@Observable
|
|
145
|
+
final class Router {
|
|
146
|
+
var path = NavigationPath()
|
|
147
|
+
|
|
148
|
+
func navigate(to destination: Destination) {
|
|
149
|
+
path.append(destination)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
func popToRoot() {
|
|
153
|
+
path = NavigationPath()
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
enum Destination: Hashable {
|
|
158
|
+
case detail(Item.ID)
|
|
159
|
+
case settings
|
|
160
|
+
case profile(User.ID)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
struct RootView: View {
|
|
164
|
+
@State private var router = Router()
|
|
165
|
+
|
|
166
|
+
var body: some View {
|
|
167
|
+
NavigationStack(path: $router.path) {
|
|
168
|
+
HomeView()
|
|
169
|
+
.navigationDestination(for: Destination.self) { dest in
|
|
170
|
+
switch dest {
|
|
171
|
+
case .detail(let id): ItemDetailView(itemID: id)
|
|
172
|
+
case .settings: SettingsView()
|
|
173
|
+
case .profile(let id): ProfileView(userID: id)
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
.environment(router)
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Performance
|
|
183
|
+
|
|
184
|
+
### Use Lazy Containers for Large Collections
|
|
185
|
+
|
|
186
|
+
`LazyVStack` and `LazyHStack` create views only when visible:
|
|
187
|
+
|
|
188
|
+
```swift
|
|
189
|
+
ScrollView {
|
|
190
|
+
LazyVStack(spacing: 8) {
|
|
191
|
+
ForEach(items) { item in
|
|
192
|
+
ItemRow(item: item)
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Stable Identifiers
|
|
199
|
+
|
|
200
|
+
Always use stable, unique IDs in `ForEach` — avoid using array indices:
|
|
201
|
+
|
|
202
|
+
```swift
|
|
203
|
+
// Use Identifiable conformance or explicit id
|
|
204
|
+
ForEach(items, id: \.stableID) { item in
|
|
205
|
+
ItemRow(item: item)
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Avoid Expensive Work in body
|
|
210
|
+
|
|
211
|
+
- Never perform I/O, network calls, or heavy computation inside `body`
|
|
212
|
+
- Use `.task {}` for async work — it cancels automatically when the view disappears
|
|
213
|
+
- Use `.sensoryFeedback()` and `.geometryGroup()` sparingly in scroll views
|
|
214
|
+
- Minimize `.shadow()`, `.blur()`, and `.mask()` in lists — they trigger offscreen rendering
|
|
215
|
+
|
|
216
|
+
### Equatable Conformance
|
|
217
|
+
|
|
218
|
+
For views with expensive bodies, conform to `Equatable` to skip unnecessary re-renders:
|
|
219
|
+
|
|
220
|
+
```swift
|
|
221
|
+
struct ExpensiveChartView: View, Equatable {
|
|
222
|
+
let dataPoints: [DataPoint] // DataPoint must conform to Equatable
|
|
223
|
+
|
|
224
|
+
static func == (lhs: Self, rhs: Self) -> Bool {
|
|
225
|
+
lhs.dataPoints == rhs.dataPoints
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
var body: some View {
|
|
229
|
+
// Complex chart rendering
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## Previews
|
|
235
|
+
|
|
236
|
+
Use `#Preview` macro with inline mock data for fast iteration:
|
|
237
|
+
|
|
238
|
+
```swift
|
|
239
|
+
#Preview("Empty state") {
|
|
240
|
+
ItemListView(viewModel: ItemListViewModel(repository: EmptyMockRepository()))
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
#Preview("Loaded") {
|
|
244
|
+
ItemListView(viewModel: ItemListViewModel(repository: PopulatedMockRepository()))
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
## Anti-Patterns to Avoid
|
|
249
|
+
|
|
250
|
+
- Using `ObservableObject` / `@Published` / `@StateObject` / `@EnvironmentObject` in new code — migrate to `@Observable`
|
|
251
|
+
- Putting async work directly in `body` or `init` — use `.task {}` or explicit load methods
|
|
252
|
+
- Creating view models as `@State` inside child views that don't own the data — pass from parent instead
|
|
253
|
+
- Using `AnyView` type erasure — prefer `@ViewBuilder` or `Group` for conditional views
|
|
254
|
+
- Ignoring `Sendable` requirements when passing data to/from actors
|
|
255
|
+
|
|
256
|
+
## References
|
|
257
|
+
|
|
258
|
+
See skill: `swift-actor-persistence` for actor-based persistence patterns.
|
|
259
|
+
See skill: `swift-protocol-di-testing` for protocol-based DI and testing with Swift Testing.
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: terminal-ops
|
|
3
|
+
description: Evidence-first repo execution workflow for ECC. Use when the user wants a command run, a repo checked, a CI failure debugged, or a narrow fix pushed with exact proof of what was executed and verified.
|
|
4
|
+
origin: ECC
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Terminal Ops
|
|
8
|
+
|
|
9
|
+
Use this when the user wants real repo execution: run commands, inspect git state, debug CI or builds, make a narrow fix, and report exactly what changed and what was verified.
|
|
10
|
+
|
|
11
|
+
This skill is intentionally narrower than general coding guidance. It is an operator workflow for evidence-first terminal execution.
|
|
12
|
+
|
|
13
|
+
## Skill Stack
|
|
14
|
+
|
|
15
|
+
Pull these ECC-native skills into the workflow when relevant:
|
|
16
|
+
|
|
17
|
+
- `verification-loop` for exact proving steps after changes
|
|
18
|
+
- `tdd-workflow` when the right fix needs regression coverage
|
|
19
|
+
- `security-review` when secrets, auth, or external inputs are involved
|
|
20
|
+
- `github-ops` when the task depends on CI runs, PR state, or release status
|
|
21
|
+
- `knowledge-ops` when the verified outcome needs to be captured into durable project context
|
|
22
|
+
|
|
23
|
+
## When to Use
|
|
24
|
+
|
|
25
|
+
- user says "fix", "debug", "run this", "check the repo", or "push it"
|
|
26
|
+
- the task depends on command output, git state, test results, or a verified local fix
|
|
27
|
+
- the answer must distinguish changed locally, verified locally, committed, and pushed
|
|
28
|
+
|
|
29
|
+
## Guardrails
|
|
30
|
+
|
|
31
|
+
- inspect before editing
|
|
32
|
+
- stay read-only if the user asked for audit/review only
|
|
33
|
+
- prefer repo-local scripts and helpers over improvised ad hoc wrappers
|
|
34
|
+
- do not claim fixed until the proving command was rerun
|
|
35
|
+
- do not claim pushed unless the branch actually moved upstream
|
|
36
|
+
|
|
37
|
+
## Workflow
|
|
38
|
+
|
|
39
|
+
### 1. Resolve the working surface
|
|
40
|
+
|
|
41
|
+
Settle:
|
|
42
|
+
|
|
43
|
+
- exact repo path
|
|
44
|
+
- branch
|
|
45
|
+
- local diff state
|
|
46
|
+
- requested mode:
|
|
47
|
+
- inspect
|
|
48
|
+
- fix
|
|
49
|
+
- verify
|
|
50
|
+
- push
|
|
51
|
+
|
|
52
|
+
### 2. Read the failing surface first
|
|
53
|
+
|
|
54
|
+
Before changing anything:
|
|
55
|
+
|
|
56
|
+
- inspect the error
|
|
57
|
+
- inspect the file or test
|
|
58
|
+
- inspect git state
|
|
59
|
+
- use any already-supplied logs or context before re-reading blindly
|
|
60
|
+
|
|
61
|
+
### 3. Keep the fix narrow
|
|
62
|
+
|
|
63
|
+
Solve one dominant failure at a time:
|
|
64
|
+
|
|
65
|
+
- use the smallest useful proving command first
|
|
66
|
+
- only escalate to a bigger build/test pass after the local failure is addressed
|
|
67
|
+
- if a command keeps failing with the same signature, stop broad retries and narrow scope
|
|
68
|
+
|
|
69
|
+
### 4. Report exact execution state
|
|
70
|
+
|
|
71
|
+
Use exact status words:
|
|
72
|
+
|
|
73
|
+
- inspected
|
|
74
|
+
- changed locally
|
|
75
|
+
- verified locally
|
|
76
|
+
- committed
|
|
77
|
+
- pushed
|
|
78
|
+
- blocked
|
|
79
|
+
|
|
80
|
+
## Output Format
|
|
81
|
+
|
|
82
|
+
```text
|
|
83
|
+
SURFACE
|
|
84
|
+
- repo
|
|
85
|
+
- branch
|
|
86
|
+
- requested mode
|
|
87
|
+
|
|
88
|
+
EVIDENCE
|
|
89
|
+
- failing command / diff / test
|
|
90
|
+
|
|
91
|
+
ACTION
|
|
92
|
+
- what changed
|
|
93
|
+
|
|
94
|
+
STATUS
|
|
95
|
+
- inspected / changed locally / verified locally / committed / pushed / blocked
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Pitfalls
|
|
99
|
+
|
|
100
|
+
- do not work from stale memory when the live repo state can be read
|
|
101
|
+
- do not widen a narrow fix into repo-wide churn
|
|
102
|
+
- do not use destructive git commands
|
|
103
|
+
- do not ignore unrelated local work
|
|
104
|
+
|
|
105
|
+
## Verification
|
|
106
|
+
|
|
107
|
+
- the response names the proving command or test
|
|
108
|
+
- git-related work names the repo path and branch
|
|
109
|
+
- any push claim includes the target branch and exact result
|