@devo-bmad-custom/agent-orchestration 1.0.6 → 1.0.8

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.
Files changed (71) hide show
  1. package/package.json +4 -2
  2. package/src/.agents/skills/tmux-commands/SKILL.md +1 -1
  3. package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/vision-framework/SKILL.md +475 -0
  4. package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/vision-framework/references/vision-requests.md +736 -0
  5. package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/vision-framework/references/visionkit-scanner.md +738 -0
  6. package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/weatherkit/SKILL.md +410 -0
  7. package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/weatherkit/references/weatherkit-patterns.md +567 -0
  8. package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/widgetkit/SKILL.md +497 -0
  9. package/src/.agents/skills/ui-ux-pro-custom/data/swift-ios-skills/widgetkit/references/widgetkit-advanced.md +871 -0
  10. package/src/.agents/skills/ui-ux-pro-custom/data/typography.csv +58 -0
  11. package/src/.agents/skills/ui-ux-pro-custom/data/ui-reasoning.csv +101 -0
  12. package/src/.agents/skills/ui-ux-pro-custom/data/ux-guidelines.csv +100 -0
  13. package/src/.agents/skills/ui-ux-pro-custom/data/web-interface.csv +31 -0
  14. package/src/.agents/skills/ui-ux-pro-custom/scripts/core.py +253 -0
  15. package/src/.agents/skills/ui-ux-pro-custom/scripts/design_system.py +1067 -0
  16. package/src/.agents/skills/ui-ux-pro-custom/scripts/search.py +114 -0
  17. package/src/.agents/skills/ux-audit/SKILL.md +151 -0
  18. package/src/.agents/skills/websocket-engineer/SKILL.md +168 -0
  19. package/src/.agents/skills/websocket-engineer/references/alternatives.md +391 -0
  20. package/src/.agents/skills/websocket-engineer/references/patterns.md +400 -0
  21. package/src/.agents/skills/websocket-engineer/references/protocol.md +195 -0
  22. package/src/.agents/skills/websocket-engineer/references/scaling.md +333 -0
  23. package/src/.agents/skills/websocket-engineer/references/security.md +474 -0
  24. package/src/.agents/skills/writing-skills/SKILL.md +655 -0
  25. package/src/.agents/skills/writing-skills/anthropic-best-practices.md +1150 -0
  26. package/src/.agents/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -0
  27. package/src/.agents/skills/writing-skills/graphviz-conventions.dot +172 -0
  28. package/src/.agents/skills/writing-skills/persuasion-principles.md +187 -0
  29. package/src/.agents/skills/writing-skills/render-graphs.js +168 -0
  30. package/src/.agents/skills/writing-skills/testing-skills-with-subagents.md +384 -0
  31. package/src/.claude/commands/bmad-master.md +15 -0
  32. package/src/.claude/commands/bmad-review-dry-loop.md +15 -0
  33. package/src/.claude/commands/bmad-review-dry.md +15 -0
  34. package/src/.claude/commands/bmad-review-security-loop.md +15 -0
  35. package/src/.claude/commands/bmad-review-security.md +15 -0
  36. package/src/.claude/commands/bmad-review-ui-loop.md +15 -0
  37. package/src/.claude/commands/bmad-review-ui.md +15 -0
  38. package/src/.claude/commands/bmad-track-compact.md +19 -0
  39. package/src/.claude/commands/bmad-track-extended.md +19 -0
  40. package/src/.claude/commands/bmad-track-large.md +19 -0
  41. package/src/.claude/commands/bmad-track-medium.md +19 -0
  42. package/src/.claude/commands/bmad-track-nano.md +19 -0
  43. package/src/.claude/commands/bmad-track-rv.md +18 -0
  44. package/src/.claude/commands/bmad-track-small.md +19 -0
  45. package/src/.claude/commands/bmad-triage.md +15 -0
  46. package/src/.claude/commands/master-orchestrator.md +15 -0
  47. package/src/_memory/master-orchestrator-sidecar/docs-index.md +3 -0
  48. package/src/_memory/master-orchestrator-sidecar/instructions.md +2616 -0
  49. package/src/_memory/master-orchestrator-sidecar/memories.md +8 -0
  50. package/src/_memory/master-orchestrator-sidecar/session-state.md +15 -0
  51. package/src/_memory/master-orchestrator-sidecar/triage-history.md +3 -0
  52. package/src/_memory/master-orchestrator-sidecar/workflows-overview.html +1230 -0
  53. package/src/core/agents/master-orchestrator.md +54 -0
  54. package/src/docs/dev/tmux/actions_popup.py +291 -0
  55. package/src/docs/dev/tmux/actions_popup.sh +110 -0
  56. package/src/docs/dev/tmux/claude_usage.sh +15 -0
  57. package/src/docs/dev/tmux/colors.conf +26 -0
  58. package/src/docs/dev/tmux/cpu_usage.sh +7 -0
  59. package/src/docs/dev/tmux/dispatch.sh +10 -0
  60. package/src/docs/dev/tmux/float_init.sh +13 -0
  61. package/src/docs/dev/tmux/float_term.sh +23 -0
  62. package/src/docs/dev/tmux/open_clip.sh +14 -0
  63. package/src/docs/dev/tmux/paste_claude.sh +26 -0
  64. package/src/docs/dev/tmux/paste_clipboard.sh +13 -0
  65. package/src/docs/dev/tmux/paste_image_wrapper.sh +98 -0
  66. package/src/docs/dev/tmux/ram_usage.sh +3 -0
  67. package/src/docs/dev/tmux/title_sync.sh +54 -0
  68. package/src/docs/dev/tmux/tmux-setup.md +867 -0
  69. package/src/docs/dev/tmux/tmux-test.sh +255 -0
  70. package/src/docs/dev/tmux/tmux.conf +127 -0
  71. package/src/docs/dev/tmux/xclip +18 -0
@@ -0,0 +1,567 @@
1
+ # WeatherKit Extended Patterns
2
+
3
+ Overflow reference for the `weatherkit` skill. Contains advanced patterns that exceed the main skill file's scope.
4
+
5
+ ## Contents
6
+
7
+ - [WeatherKit SwiftUI Integration](#weatherkit-swiftui-integration)
8
+ - [Charts Integration](#charts-integration)
9
+ - [Historical Weather Statistics](#historical-weather-statistics)
10
+ - [Weather Condition Mapping](#weather-condition-mapping)
11
+ - [Caching Strategy](#caching-strategy)
12
+ - [Location-Based Weather](#location-based-weather)
13
+
14
+ ## WeatherKit SwiftUI Integration
15
+
16
+ ### Weather Manager with @Observable
17
+
18
+ ```swift
19
+ import WeatherKit
20
+ import CoreLocation
21
+
22
+ @Observable
23
+ @MainActor
24
+ final class WeatherManager {
25
+ private let service = WeatherService.shared
26
+
27
+ var current: CurrentWeather?
28
+ var hourlyForecast: Forecast<HourWeather>?
29
+ var dailyForecast: Forecast<DayWeather>?
30
+ var alerts: [WeatherAlert]?
31
+ var attribution: WeatherAttribution?
32
+ var isLoading = false
33
+ var error: Error?
34
+
35
+ func fetchWeather(for location: CLLocation) async {
36
+ isLoading = true
37
+ error = nil
38
+
39
+ do {
40
+ let (current, hourly, daily, alerts) = try await service.weather(
41
+ for: location,
42
+ including: .current, .hourly, .daily, .alerts
43
+ )
44
+ self.current = current
45
+ self.hourlyForecast = hourly
46
+ self.dailyForecast = daily
47
+ self.alerts = alerts
48
+ self.attribution = try await service.attribution
49
+ } catch {
50
+ self.error = error
51
+ }
52
+
53
+ isLoading = false
54
+ }
55
+ }
56
+ ```
57
+
58
+ ### Weather Dashboard View
59
+
60
+ ```swift
61
+ import SwiftUI
62
+ import WeatherKit
63
+
64
+ struct WeatherDashboardView: View {
65
+ @Environment(WeatherManager.self) private var manager
66
+ let location: CLLocation
67
+
68
+ var body: some View {
69
+ NavigationStack {
70
+ ScrollView {
71
+ VStack(spacing: 20) {
72
+ if manager.isLoading {
73
+ ProgressView("Loading weather...")
74
+ } else if let current = manager.current {
75
+ currentConditionsCard(current)
76
+ }
77
+
78
+ if let hourly = manager.hourlyForecast {
79
+ hourlyForecastSection(hourly)
80
+ }
81
+
82
+ if let daily = manager.dailyForecast {
83
+ dailyForecastSection(daily)
84
+ }
85
+
86
+ if let alerts = manager.alerts, !alerts.isEmpty {
87
+ alertsSection(alerts)
88
+ }
89
+
90
+ if let attribution = manager.attribution {
91
+ WeatherAttributionView(attribution: attribution)
92
+ }
93
+ }
94
+ .padding()
95
+ }
96
+ .navigationTitle("Weather")
97
+ .task {
98
+ await manager.fetchWeather(for: location)
99
+ }
100
+ .refreshable {
101
+ await manager.fetchWeather(for: location)
102
+ }
103
+ }
104
+ }
105
+
106
+ private func currentConditionsCard(_ current: CurrentWeather) -> some View {
107
+ VStack(spacing: 12) {
108
+ Image(systemName: current.symbolName)
109
+ .font(.system(size: 60))
110
+ .symbolRenderingMode(.multicolor)
111
+
112
+ Text(current.temperature.formatted())
113
+ .font(.system(size: 48, weight: .thin))
114
+
115
+ Text(current.condition.description)
116
+ .font(.title3)
117
+ .foregroundStyle(.secondary)
118
+
119
+ HStack(spacing: 24) {
120
+ Label(
121
+ "Humidity \(current.humidity.formatted(.percent))",
122
+ systemImage: "humidity"
123
+ )
124
+ Label(
125
+ "Wind \(current.wind.speed.formatted())",
126
+ systemImage: "wind"
127
+ )
128
+ Label(
129
+ "UV \(current.uvIndex.value)",
130
+ systemImage: "sun.max"
131
+ )
132
+ }
133
+ .font(.caption)
134
+ }
135
+ .padding()
136
+ }
137
+
138
+ private func hourlyForecastSection(_ forecast: Forecast<HourWeather>) -> some View {
139
+ VStack(alignment: .leading) {
140
+ Text("Hourly Forecast")
141
+ .font(.headline)
142
+
143
+ ScrollView(.horizontal, showsIndicators: false) {
144
+ HStack(spacing: 16) {
145
+ ForEach(Array(forecast.prefix(12)), id: \.date) { hour in
146
+ VStack(spacing: 8) {
147
+ Text(hour.date, format: .dateTime.hour())
148
+ .font(.caption)
149
+ Image(systemName: hour.symbolName)
150
+ .symbolRenderingMode(.multicolor)
151
+ Text(hour.temperature.formatted())
152
+ .font(.subheadline)
153
+ }
154
+ }
155
+ }
156
+ }
157
+ }
158
+ }
159
+
160
+ private func dailyForecastSection(_ forecast: Forecast<DayWeather>) -> some View {
161
+ VStack(alignment: .leading) {
162
+ Text("10-Day Forecast")
163
+ .font(.headline)
164
+
165
+ ForEach(Array(forecast), id: \.date) { day in
166
+ HStack {
167
+ Text(day.date, format: .dateTime.weekday(.abbreviated))
168
+ .frame(width: 40, alignment: .leading)
169
+
170
+ Image(systemName: day.symbolName)
171
+ .symbolRenderingMode(.multicolor)
172
+ .frame(width: 30)
173
+
174
+ Text(day.lowTemperature.formatted())
175
+ .foregroundStyle(.secondary)
176
+ .frame(width: 50, alignment: .trailing)
177
+
178
+ temperatureBar(low: day.lowTemperature, high: day.highTemperature)
179
+
180
+ Text(day.highTemperature.formatted())
181
+ .frame(width: 50)
182
+ }
183
+ .font(.subheadline)
184
+ }
185
+ }
186
+ }
187
+
188
+ private func temperatureBar(
189
+ low: Measurement<UnitTemperature>,
190
+ high: Measurement<UnitTemperature>
191
+ ) -> some View {
192
+ Capsule()
193
+ .fill(.linearGradient(
194
+ colors: [.blue, .orange],
195
+ startPoint: .leading,
196
+ endPoint: .trailing
197
+ ))
198
+ .frame(height: 4)
199
+ .containerRelativeFrame(.horizontal) { length, _ in
200
+ length * 0.3
201
+ }
202
+ }
203
+
204
+ private func alertsSection(_ alerts: [WeatherAlert]) -> some View {
205
+ VStack(alignment: .leading) {
206
+ Text("Weather Alerts")
207
+ .font(.headline)
208
+
209
+ ForEach(alerts, id: \.detailsURL) { alert in
210
+ HStack {
211
+ Image(systemName: "exclamationmark.triangle.fill")
212
+ .foregroundStyle(alert.severity == .extreme ? .red : .orange)
213
+ VStack(alignment: .leading) {
214
+ Text(alert.summary)
215
+ .font(.subheadline)
216
+ Text(alert.region)
217
+ .font(.caption)
218
+ .foregroundStyle(.secondary)
219
+ }
220
+ }
221
+ .padding()
222
+ .background(.yellow.opacity(0.1))
223
+ .clipShape(RoundedRectangle(cornerRadius: 8))
224
+ }
225
+ }
226
+ }
227
+ }
228
+ ```
229
+
230
+ ### Attribution View
231
+
232
+ ```swift
233
+ struct WeatherAttributionView: View {
234
+ let attribution: WeatherAttribution
235
+ @Environment(\.colorScheme) private var colorScheme
236
+
237
+ var body: some View {
238
+ VStack(spacing: 4) {
239
+ AsyncImage(url: markURL) { image in
240
+ image
241
+ .resizable()
242
+ .scaledToFit()
243
+ .frame(height: 12)
244
+ } placeholder: {
245
+ Text(attribution.serviceName)
246
+ .font(.caption2)
247
+ }
248
+
249
+ Link(destination: attribution.legalPageURL) {
250
+ Text("Data Sources")
251
+ .font(.caption2)
252
+ .foregroundStyle(.secondary)
253
+ }
254
+ }
255
+ .padding(.vertical, 8)
256
+ }
257
+
258
+ private var markURL: URL {
259
+ colorScheme == .dark
260
+ ? attribution.combinedMarkDarkURL
261
+ : attribution.combinedMarkLightURL
262
+ }
263
+ }
264
+ ```
265
+
266
+ ## Charts Integration
267
+
268
+ ### Hourly Temperature Chart
269
+
270
+ ```swift
271
+ import SwiftUI
272
+ import Charts
273
+ import WeatherKit
274
+
275
+ struct HourlyTemperatureChart: View {
276
+ let forecast: Forecast<HourWeather>
277
+
278
+ var body: some View {
279
+ Chart(Array(forecast.prefix(24)), id: \.date) { hour in
280
+ LineMark(
281
+ x: .value("Hour", hour.date),
282
+ y: .value("Temperature", hour.temperature.converted(to: .celsius).value)
283
+ )
284
+ .interpolationMethod(.catmullRom)
285
+ .foregroundStyle(.orange)
286
+
287
+ AreaMark(
288
+ x: .value("Hour", hour.date),
289
+ y: .value("Temperature", hour.temperature.converted(to: .celsius).value)
290
+ )
291
+ .interpolationMethod(.catmullRom)
292
+ .foregroundStyle(.orange.opacity(0.1))
293
+ }
294
+ .chartYAxisLabel("Temperature (C)")
295
+ .chartXAxis {
296
+ AxisMarks(values: .stride(by: .hour, count: 3)) { _ in
297
+ AxisGridLine()
298
+ AxisValueLabel(format: .dateTime.hour())
299
+ }
300
+ }
301
+ .frame(height: 200)
302
+ }
303
+ }
304
+ ```
305
+
306
+ ### Daily Precipitation Chart
307
+
308
+ ```swift
309
+ struct DailyPrecipitationChart: View {
310
+ let forecast: Forecast<DayWeather>
311
+
312
+ var body: some View {
313
+ Chart(Array(forecast), id: \.date) { day in
314
+ BarMark(
315
+ x: .value("Day", day.date, unit: .day),
316
+ y: .value("Chance", day.precipitationChance)
317
+ )
318
+ .foregroundStyle(.blue.gradient)
319
+ }
320
+ .chartYScale(domain: 0...1)
321
+ .chartYAxis {
322
+ AxisMarks(format: .percent)
323
+ }
324
+ .chartXAxis {
325
+ AxisMarks(values: .stride(by: .day)) { _ in
326
+ AxisGridLine()
327
+ AxisValueLabel(format: .dateTime.weekday(.abbreviated))
328
+ }
329
+ }
330
+ .frame(height: 150)
331
+ }
332
+ }
333
+ ```
334
+
335
+ ## Historical Weather Statistics
336
+
337
+ WeatherKit provides historical weather data through daily and monthly statistics.
338
+
339
+ ### Daily Statistics
340
+
341
+ ```swift
342
+ func fetchDailyStats(
343
+ for location: CLLocation,
344
+ dateRange: DateInterval
345
+ ) async throws {
346
+ let stats = try await WeatherService.shared.dailyStatistics(
347
+ for: location,
348
+ forDaysIn: dateRange,
349
+ including: [.temperature, .precipitation]
350
+ )
351
+
352
+ for dayStat in stats {
353
+ print("Date: \(dayStat.date)")
354
+ if let temp = dayStat.statistics(for: .temperature) {
355
+ print(" Avg temp: \(temp.mean?.formatted() ?? "N/A")")
356
+ print(" Min temp: \(temp.minimum?.formatted() ?? "N/A")")
357
+ print(" Max temp: \(temp.maximum?.formatted() ?? "N/A")")
358
+ }
359
+ }
360
+ }
361
+ ```
362
+
363
+ ### Monthly Statistics
364
+
365
+ ```swift
366
+ func fetchMonthlyStats(for location: CLLocation) async throws {
367
+ let stats = try await WeatherService.shared.monthlyStatistics(
368
+ for: location,
369
+ including: [.temperature, .precipitation]
370
+ )
371
+
372
+ for monthStat in stats {
373
+ print("Month: \(monthStat.month)")
374
+ }
375
+ }
376
+ ```
377
+
378
+ ## Weather Condition Mapping
379
+
380
+ ### Mapping Conditions to Colors
381
+
382
+ ```swift
383
+ extension WeatherCondition {
384
+ var themeColor: Color {
385
+ switch self {
386
+ case .clear, .mostlyClear:
387
+ return .yellow
388
+ case .partlyCloudy, .mostlyCloudy, .cloudy:
389
+ return .gray
390
+ case .rain, .heavyRain, .drizzle:
391
+ return .blue
392
+ case .snow, .heavySnow, .flurries, .sleet, .freezingRain,
393
+ .freezingDrizzle, .wintryMix, .blizzard:
394
+ return .cyan
395
+ case .thunderstorms, .strongStorms, .tropicalStorm, .hurricane:
396
+ return .purple
397
+ case .foggy, .haze, .smoky:
398
+ return .gray.opacity(0.6)
399
+ case .breezy, .windy:
400
+ return .teal
401
+ case .hot:
402
+ return .red
403
+ case .frigid, .blowingDust:
404
+ return .indigo
405
+ @unknown default:
406
+ return .primary
407
+ }
408
+ }
409
+ }
410
+ ```
411
+
412
+ ### Mapping Severity to Priority
413
+
414
+ ```swift
415
+ extension WeatherSeverity {
416
+ var displayPriority: Int {
417
+ switch self {
418
+ case .extreme:
419
+ return 4
420
+ case .severe:
421
+ return 3
422
+ case .moderate:
423
+ return 2
424
+ case .minor:
425
+ return 1
426
+ case .unknown:
427
+ return 0
428
+ @unknown default:
429
+ return 0
430
+ }
431
+ }
432
+ }
433
+ ```
434
+
435
+ ## Caching Strategy
436
+
437
+ ### Actor-Based Weather Cache
438
+
439
+ ```swift
440
+ actor WeatherCache {
441
+ struct CacheEntry {
442
+ let weather: CurrentWeather
443
+ let hourly: Forecast<HourWeather>
444
+ let daily: Forecast<DayWeather>
445
+ let fetchDate: Date
446
+ }
447
+
448
+ private var cache: [String: CacheEntry] = [:]
449
+ private let staleness: TimeInterval
450
+
451
+ init(staleness: TimeInterval = 600) { // 10 minutes default
452
+ self.staleness = staleness
453
+ }
454
+
455
+ func get(for key: String) -> CacheEntry? {
456
+ guard let entry = cache[key],
457
+ Date.now.timeIntervalSince(entry.fetchDate) < staleness else {
458
+ cache[key] = nil
459
+ return nil
460
+ }
461
+ return entry
462
+ }
463
+
464
+ func set(_ entry: CacheEntry, for key: String) {
465
+ cache[key] = entry
466
+ }
467
+
468
+ /// Generate a cache key from a location (rounded to ~1km precision)
469
+ static func key(for location: CLLocation) -> String {
470
+ let lat = (location.coordinate.latitude * 100).rounded() / 100
471
+ let lon = (location.coordinate.longitude * 100).rounded() / 100
472
+ return "\(lat),\(lon)"
473
+ }
474
+ }
475
+ ```
476
+
477
+ ### Using the Cache
478
+
479
+ ```swift
480
+ @Observable
481
+ @MainActor
482
+ final class CachedWeatherManager {
483
+ private let service = WeatherService.shared
484
+ private let cache = WeatherCache()
485
+
486
+ var current: CurrentWeather?
487
+
488
+ func fetchWeather(for location: CLLocation) async throws {
489
+ let key = WeatherCache.key(for: location)
490
+
491
+ if let cached = await cache.get(for: key) {
492
+ current = cached.weather
493
+ return
494
+ }
495
+
496
+ let (current, hourly, daily) = try await service.weather(
497
+ for: location,
498
+ including: .current, .hourly, .daily
499
+ )
500
+
501
+ let entry = WeatherCache.CacheEntry(
502
+ weather: current,
503
+ hourly: hourly,
504
+ daily: daily,
505
+ fetchDate: .now
506
+ )
507
+ await cache.set(entry, for: key)
508
+ self.current = current
509
+ }
510
+ }
511
+ ```
512
+
513
+ ## Location-Based Weather
514
+
515
+ ### Combining CoreLocation with WeatherKit
516
+
517
+ ```swift
518
+ import CoreLocation
519
+ import WeatherKit
520
+
521
+ @Observable
522
+ @MainActor
523
+ final class LocationWeatherManager: NSObject, CLLocationManagerDelegate {
524
+ private let locationManager = CLLocationManager()
525
+ private let weatherService = WeatherService.shared
526
+
527
+ var current: CurrentWeather?
528
+ var locationError: Error?
529
+
530
+ override init() {
531
+ super.init()
532
+ locationManager.delegate = self
533
+ locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
534
+ }
535
+
536
+ func requestWeather() {
537
+ locationManager.requestWhenInUseAuthorization()
538
+ locationManager.requestLocation()
539
+ }
540
+
541
+ nonisolated func locationManager(
542
+ _ manager: CLLocationManager,
543
+ didUpdateLocations locations: [CLLocation]
544
+ ) {
545
+ guard let location = locations.last else { return }
546
+ Task { @MainActor in
547
+ do {
548
+ current = try await weatherService.weather(
549
+ for: location,
550
+ including: .current
551
+ )
552
+ } catch {
553
+ locationError = error
554
+ }
555
+ }
556
+ }
557
+
558
+ nonisolated func locationManager(
559
+ _ manager: CLLocationManager,
560
+ didFailWithError error: Error
561
+ ) {
562
+ Task { @MainActor in
563
+ locationError = error
564
+ }
565
+ }
566
+ }
567
+ ```