@mmerterden/multi-agent-pipeline 20.36.0 → 20.37.1

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 (222) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/docs/facts.json +2 -2
  3. package/docs/features.md +1 -1
  4. package/docs/recovery-guide.md +1 -1
  5. package/install/catalog-history.json +1 -1
  6. package/manifest.json +225 -148
  7. package/package.json +1 -1
  8. package/pipeline/commands/multi-agent/SKILL.md +33 -154
  9. package/pipeline/commands/multi-agent/analysis/SKILL.md +14 -68
  10. package/pipeline/commands/multi-agent/analysis-jira/SKILL.md +5 -8
  11. package/pipeline/commands/multi-agent/autopilot-on/SKILL.md +38 -109
  12. package/pipeline/commands/multi-agent/channels/SKILL.md +38 -167
  13. package/pipeline/commands/multi-agent/complaint-analysis/SKILL.md +37 -144
  14. package/pipeline/commands/multi-agent/design-check/SKILL.md +27 -131
  15. package/pipeline/commands/multi-agent/garbage-collect/SKILL.md +22 -48
  16. package/pipeline/commands/multi-agent/ios-coding-standard/SKILL.md +37 -180
  17. package/pipeline/commands/multi-agent/jira/SKILL.md +16 -46
  18. package/pipeline/commands/multi-agent/manual-test/SKILL.md +12 -7
  19. package/pipeline/commands/multi-agent/refactor/SKILL.md +23 -184
  20. package/pipeline/commands/multi-agent/resume/SKILL.md +30 -136
  21. package/pipeline/commands/multi-agent/review/SKILL.md +24 -199
  22. package/pipeline/commands/multi-agent/setup/SKILL.md +25 -181
  23. package/pipeline/commands/multi-agent/stack/SKILL.md +9 -53
  24. package/pipeline/commands/multi-agent/status/SKILL.md +13 -2
  25. package/pipeline/commands/multi-agent/store-ready/SKILL.md +27 -226
  26. package/pipeline/commands/multi-agent/sync/SKILL.md +35 -164
  27. package/pipeline/commands/multi-agent/test-gen/SKILL.md +2 -4
  28. package/pipeline/commands/multi-agent/update/SKILL.md +18 -60
  29. package/pipeline/contract/CHANGELOG.md +9 -0
  30. package/pipeline/contract/fixtures/error-invalid-request.json +1 -1
  31. package/pipeline/contract/fixtures/error-unauthorized.json +1 -1
  32. package/pipeline/contract/fixtures/error-unsigned.json +1 -1
  33. package/pipeline/contract/fixtures/runs-awaiting-question.json +1 -1
  34. package/pipeline/contract/fixtures/runs-empty.json +1 -1
  35. package/pipeline/contract/fixtures/runs-failed.json +1 -1
  36. package/pipeline/contract/fixtures/runs-pr-opened-redacted.json +1 -1
  37. package/pipeline/contract/fixtures/runs-pr-opened.json +1 -1
  38. package/pipeline/contract/fixtures/runs-running.json +1 -1
  39. package/pipeline/contract/manifest.json +5 -5
  40. package/pipeline/contract/types/index.d.ts +3 -2
  41. package/pipeline/multi-agent-refs/audit-guide.md +20 -0
  42. package/pipeline/multi-agent-refs/autopilot-on/details.md +148 -0
  43. package/pipeline/multi-agent-refs/channels/generator.md +14 -0
  44. package/pipeline/multi-agent-refs/channels/preview.md +13 -0
  45. package/pipeline/multi-agent-refs/channels/reference.md +46 -0
  46. package/pipeline/multi-agent-refs/complaint-analysis/phases.md +159 -0
  47. package/pipeline/multi-agent-refs/design-check/export.md +1 -0
  48. package/pipeline/multi-agent-refs/design-check/init-inventory.md +1 -1
  49. package/pipeline/multi-agent-refs/design-check/scope-and-ledger.md +64 -0
  50. package/pipeline/multi-agent-refs/features/analysis-command-notes.md +53 -0
  51. package/pipeline/multi-agent-refs/features/commit-multi-repo.md +63 -0
  52. package/pipeline/multi-agent-refs/features/dev-multi-repo.md +51 -0
  53. package/pipeline/multi-agent-refs/features/test-gap.md +40 -0
  54. package/pipeline/multi-agent-refs/features/worktree-finalize.md +1 -1
  55. package/pipeline/multi-agent-refs/garbage-collect/phases.md +60 -0
  56. package/pipeline/multi-agent-refs/ios-coding-standard/plan.md +71 -0
  57. package/pipeline/multi-agent-refs/ios-coding-standard/resolve-and-scan.md +135 -0
  58. package/pipeline/multi-agent-refs/jira/picker-detail.md +71 -0
  59. package/pipeline/multi-agent-refs/orchestrator/copilot-pipeline.md +88 -0
  60. package/pipeline/multi-agent-refs/orchestrator/dispatcher.md +96 -1
  61. package/pipeline/multi-agent-refs/orchestrator/phase-3-user-test.md +12 -9
  62. package/pipeline/multi-agent-refs/phases/phase-1-plan.md +4 -4
  63. package/pipeline/multi-agent-refs/phases/phase-2-dev.md +8 -47
  64. package/pipeline/multi-agent-refs/phases/phase-3-review.md +21 -65
  65. package/pipeline/multi-agent-refs/phases/phase-4-commit.md +9 -59
  66. package/pipeline/multi-agent-refs/phases/phase-5-report.md +0 -31
  67. package/pipeline/multi-agent-refs/refactor/sweep.md +190 -0
  68. package/pipeline/multi-agent-refs/resume/details.md +115 -2
  69. package/pipeline/multi-agent-refs/review/inputs.md +33 -1
  70. package/pipeline/multi-agent-refs/review/module-guides.md +9 -1
  71. package/pipeline/multi-agent-refs/review/panel.md +75 -0
  72. package/pipeline/multi-agent-refs/review/valven.md +5 -1
  73. package/pipeline/multi-agent-refs/rules.md +1 -1
  74. package/pipeline/multi-agent-refs/setup/hooks-and-plugins.md +4 -0
  75. package/pipeline/multi-agent-refs/setup/token-save-flow.md +13 -0
  76. package/pipeline/multi-agent-refs/stack/background.md +72 -0
  77. package/pipeline/multi-agent-refs/store-ready/gates.md +139 -0
  78. package/pipeline/multi-agent-refs/store-ready/report.md +40 -2
  79. package/pipeline/multi-agent-refs/sync/office.md +10 -0
  80. package/pipeline/multi-agent-refs/sync/overview.md +61 -0
  81. package/pipeline/multi-agent-refs/sync/repo.md +91 -0
  82. package/pipeline/multi-agent-refs/update/details.md +83 -0
  83. package/pipeline/office/index.html +6 -3
  84. package/pipeline/office/toolkit.json +1 -1
  85. package/pipeline/rules/figma-pipeline.md +6 -3
  86. package/pipeline/schemas/prefs.schema.json +1 -1
  87. package/pipeline/schemas/runs-index.schema.json +2 -1
  88. package/pipeline/scripts/_memory-policy.mjs +27 -5
  89. package/pipeline/scripts/checkpoint-fold.sh +59 -0
  90. package/pipeline/scripts/contract-server.mjs +1 -1
  91. package/pipeline/scripts/gate-ledger.mjs +1 -1
  92. package/pipeline/scripts/office-control.mjs +41 -15
  93. package/pipeline/scripts/offload-ref.sh +1 -1
  94. package/pipeline/scripts/rework-rulings.mjs +5 -3
  95. package/pipeline/scripts/runs-index.mjs +34 -7
  96. package/pipeline/scripts/scope-check-gate.mjs +15 -2
  97. package/pipeline/scripts/status-overview.mjs +401 -0
  98. package/pipeline/scripts/user-test-handoff.sh +203 -0
  99. package/pipeline/scripts/validate-planning.mjs +5 -3
  100. package/pipeline/scripts/validate-triage.mjs +2 -1
  101. package/pipeline/scripts/write-state.mjs +13 -4
  102. package/pipeline/skills/.skill-manifest.json +64 -64
  103. package/pipeline/skills/shared/core/apple-archive-compliance/SKILL.md +7 -70
  104. package/pipeline/skills/shared/core/apple-archive-compliance/references/examples.md +67 -0
  105. package/pipeline/skills/shared/core/apple-archive-compliance/references/version-history.md +8 -0
  106. package/pipeline/skills/shared/core/google-play-compliance/SKILL.md +10 -72
  107. package/pipeline/skills/shared/core/google-play-compliance/references/examples.md +69 -0
  108. package/pipeline/skills/shared/core/google-play-compliance/references/notes.md +7 -0
  109. package/pipeline/skills/shared/core/google-play-compliance/references/version-history.md +5 -0
  110. package/pipeline/skills/shared/core/multi-agent/SKILL.md +39 -262
  111. package/pipeline/skills/shared/core/multi-agent-autopilot-on/SKILL.md +35 -73
  112. package/pipeline/skills/shared/core/multi-agent-channels/SKILL.md +37 -337
  113. package/pipeline/skills/shared/core/multi-agent-design-check/SKILL.md +27 -122
  114. package/pipeline/skills/shared/core/multi-agent-help/SKILL.md +8 -340
  115. package/pipeline/skills/shared/core/multi-agent-ios-coding-standard/SKILL.md +37 -180
  116. package/pipeline/skills/shared/core/multi-agent-manual-test/SKILL.md +12 -7
  117. package/pipeline/skills/shared/core/multi-agent-refactor/SKILL.md +23 -184
  118. package/pipeline/skills/shared/core/multi-agent-review/SKILL.md +14 -82
  119. package/pipeline/skills/shared/core/multi-agent-setup/SKILL.md +25 -277
  120. package/pipeline/skills/shared/core/multi-agent-status/SKILL.md +13 -2
  121. package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +73 -217
  122. package/pipeline/skills/shared/external/alarmkit/SKILL.md +11 -162
  123. package/pipeline/skills/shared/external/alarmkit/references/alarmkit-code.md +257 -0
  124. package/pipeline/skills/shared/external/android-architecture/SKILL.md +7 -58
  125. package/pipeline/skills/shared/external/android-architecture/references/code-examples.md +68 -0
  126. package/pipeline/skills/shared/external/app-intents/SKILL.md +3 -45
  127. package/pipeline/skills/shared/external/app-intents/references/code-examples.md +54 -0
  128. package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +5 -81
  129. package/pipeline/skills/shared/external/app-store-optimization/references/engagement-and-localization.md +96 -0
  130. package/pipeline/skills/shared/external/app-store-review/SKILL.md +6 -112
  131. package/pipeline/skills/shared/external/app-store-review/references/monetization-and-submission.md +138 -0
  132. package/pipeline/skills/shared/external/apple-on-device-ai/SKILL.md +10 -117
  133. package/pipeline/skills/shared/external/apple-on-device-ai/references/foundation-models-code.md +186 -0
  134. package/pipeline/skills/shared/external/authentication/SKILL.md +3 -50
  135. package/pipeline/skills/shared/external/authentication/references/code-examples.md +59 -0
  136. package/pipeline/skills/shared/external/callkit-voip/SKILL.md +3 -84
  137. package/pipeline/skills/shared/external/callkit-voip/references/code-examples.md +93 -0
  138. package/pipeline/skills/shared/external/ci-cd-pipelines/SKILL.md +7 -263
  139. package/pipeline/skills/shared/external/ci-cd-pipelines/references/pipeline-examples.md +281 -0
  140. package/pipeline/skills/shared/external/clean-code/SKILL.md +8 -41
  141. package/pipeline/skills/shared/external/clean-code/references/code-examples.md +56 -0
  142. package/pipeline/skills/shared/external/cloudkit-sync/SKILL.md +8 -146
  143. package/pipeline/skills/shared/external/cloudkit-sync/references/cloudkit-code.md +214 -0
  144. package/pipeline/skills/shared/external/compose-components/SKILL.md +6 -80
  145. package/pipeline/skills/shared/external/compose-components/references/code-examples.md +89 -0
  146. package/pipeline/skills/shared/external/compose-navigation/SKILL.md +5 -64
  147. package/pipeline/skills/shared/external/compose-navigation/references/code-examples.md +70 -0
  148. package/pipeline/skills/shared/external/core-data/SKILL.md +9 -157
  149. package/pipeline/skills/shared/external/core-data/references/core-data-code.md +221 -0
  150. package/pipeline/skills/shared/external/core-nfc/SKILL.md +3 -89
  151. package/pipeline/skills/shared/external/core-nfc/references/code-examples.md +98 -0
  152. package/pipeline/skills/shared/external/coreml/SKILL.md +17 -133
  153. package/pipeline/skills/shared/external/coreml/references/coreml-code.md +208 -0
  154. package/pipeline/skills/shared/external/css-modern/SKILL.md +8 -131
  155. package/pipeline/skills/shared/external/css-modern/references/code-examples.md +142 -0
  156. package/pipeline/skills/shared/external/database-patterns/SKILL.md +6 -103
  157. package/pipeline/skills/shared/external/database-patterns/references/orm-examples.md +112 -0
  158. package/pipeline/skills/shared/external/html-semantic/SKILL.md +7 -48
  159. package/pipeline/skills/shared/external/html-semantic/references/code-examples.md +54 -0
  160. package/pipeline/skills/shared/external/humanizer/SKILL.md +6 -19
  161. package/pipeline/skills/shared/external/humanizer/references/voice.md +24 -0
  162. package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +13 -170
  163. package/pipeline/skills/shared/external/ios-accessibility/references/assistive-tech-review.md +224 -0
  164. package/pipeline/skills/shared/external/ios-localization/SKILL.md +2 -24
  165. package/pipeline/skills/shared/external/ios-localization/references/code-examples.md +30 -0
  166. package/pipeline/skills/shared/external/ios-networking/SKILL.md +3 -58
  167. package/pipeline/skills/shared/external/ios-networking/references/code-examples.md +67 -0
  168. package/pipeline/skills/shared/external/ios-security/SKILL.md +4 -64
  169. package/pipeline/skills/shared/external/ios-security/references/code-examples.md +74 -0
  170. package/pipeline/skills/shared/external/live-activities/SKILL.md +4 -90
  171. package/pipeline/skills/shared/external/live-activities/references/code-examples.md +108 -0
  172. package/pipeline/skills/shared/external/localization-reuse-map/SKILL.md +9 -23
  173. package/pipeline/skills/shared/external/localization-reuse-map/references/project-settings.md +22 -0
  174. package/pipeline/skills/shared/external/mapkit-location/SKILL.md +5 -95
  175. package/pipeline/skills/shared/external/mapkit-location/references/code-examples.md +117 -0
  176. package/pipeline/skills/shared/external/nextjs-app-router/SKILL.md +7 -106
  177. package/pipeline/skills/shared/external/nextjs-app-router/references/app-router-examples.md +124 -0
  178. package/pipeline/skills/shared/external/permissionkit/SKILL.md +2 -31
  179. package/pipeline/skills/shared/external/permissionkit/references/code-examples.md +37 -0
  180. package/pipeline/skills/shared/external/play-store-review/SKILL.md +6 -74
  181. package/pipeline/skills/shared/external/play-store-review/references/signing-and-policies.md +83 -0
  182. package/pipeline/skills/shared/external/push-notifications/SKILL.md +8 -125
  183. package/pipeline/skills/shared/external/push-notifications/references/notification-code.md +176 -0
  184. package/pipeline/skills/shared/external/python-patterns/SKILL.md +7 -158
  185. package/pipeline/skills/shared/external/python-patterns/references/python-examples.md +176 -0
  186. package/pipeline/skills/shared/external/rest-api-design/SKILL.md +7 -157
  187. package/pipeline/skills/shared/external/rest-api-design/references/api-examples.md +175 -0
  188. package/pipeline/skills/shared/external/swift-architecture/SKILL.md +11 -230
  189. package/pipeline/skills/shared/external/swift-architecture/references/pattern-examples.md +295 -0
  190. package/pipeline/skills/shared/external/swift-codable/SKILL.md +17 -149
  191. package/pipeline/skills/shared/external/swift-codable/references/codable-recipes.md +207 -0
  192. package/pipeline/skills/shared/external/swift-concurrency/SKILL.md +12 -99
  193. package/pipeline/skills/shared/external/swift-concurrency/references/code-examples.md +100 -0
  194. package/pipeline/skills/shared/external/swift-concurrency/references/swift-6-2-additions.md +18 -0
  195. package/pipeline/skills/shared/external/swift-formatstyle/SKILL.md +9 -78
  196. package/pipeline/skills/shared/external/swift-formatstyle/references/formatstyle-examples.md +113 -0
  197. package/pipeline/skills/shared/external/swift-language/SKILL.md +3 -56
  198. package/pipeline/skills/shared/external/swift-language/references/code-examples.md +65 -0
  199. package/pipeline/skills/shared/external/swift-testing-pro/SKILL.md +1 -0
  200. package/pipeline/skills/shared/external/swiftdata/SKILL.md +6 -122
  201. package/pipeline/skills/shared/external/swiftdata/references/code-examples.md +140 -0
  202. package/pipeline/skills/shared/external/swiftui-uikit-interop/SKILL.md +12 -139
  203. package/pipeline/skills/shared/external/swiftui-uikit-interop/references/interop-code.md +198 -0
  204. package/pipeline/skills/shared/external/tailwind-css/SKILL.md +9 -81
  205. package/pipeline/skills/shared/external/tailwind-css/references/code-examples.md +91 -0
  206. package/pipeline/skills/shared/external/testing-backend/SKILL.md +7 -207
  207. package/pipeline/skills/shared/external/testing-backend/references/testing-examples.md +225 -0
  208. package/pipeline/skills/shared/external/typescript-patterns/SKILL.md +8 -89
  209. package/pipeline/skills/shared/external/typescript-patterns/references/code-examples.md +100 -0
  210. package/pipeline/skills/shared/external/vision-framework/SKILL.md +2 -20
  211. package/pipeline/skills/shared/external/vision-framework/references/code-examples.md +26 -0
  212. package/pipeline/skills/shared/external/vue-composition/SKILL.md +7 -169
  213. package/pipeline/skills/shared/external/vue-composition/references/vue-examples.md +187 -0
  214. package/pipeline/skills/shared/external/web-accessibility/SKILL.md +7 -174
  215. package/pipeline/skills/shared/external/web-accessibility/references/a11y-examples.md +192 -0
  216. package/pipeline/skills/shared/external/web-performance/SKILL.md +8 -66
  217. package/pipeline/skills/shared/external/web-performance/references/code-examples.md +77 -0
  218. package/pipeline/skills/shared/external/web-testing/SKILL.md +11 -186
  219. package/pipeline/skills/shared/external/web-testing/references/testing-examples.md +213 -0
  220. /package/pipeline/skills/shared/external/localization-reuse-map/{reference → references}/format-and-output.md +0 -0
  221. /package/pipeline/skills/shared/external/localization-reuse-map/{reference → references}/publish-and-snapshot.md +0 -0
  222. /package/pipeline/skills/shared/external/localization-reuse-map/{reference → references}/sources-and-recipes.md +0 -0
@@ -0,0 +1,100 @@
1
+ # TypeScript Code Examples
2
+
3
+ Full code samples for the SKILL.md sections that link here. The rules and the decision guidance stay in SKILL.md; each heading below matches the SKILL.md section the code belongs to.
4
+
5
+ ## Discriminated Unions
6
+
7
+ ```typescript
8
+ // API response pattern
9
+ type ApiResult<T> =
10
+ | { status: 'success'; data: T }
11
+ | { status: 'error'; error: { code: string; message: string } }
12
+ | { status: 'loading' };
13
+
14
+ function handleResult<T>(result: ApiResult<T>): string {
15
+ switch (result.status) {
16
+ case 'success':
17
+ return JSON.stringify(result.data);
18
+ case 'error':
19
+ return `Error ${result.error.code}: ${result.error.message}`;
20
+ case 'loading':
21
+ return 'Loading...';
22
+ }
23
+ }
24
+
25
+ // Event system
26
+ type AppEvent =
27
+ | { type: 'USER_LOGIN'; payload: { userId: string } }
28
+ | { type: 'USER_LOGOUT' }
29
+ | { type: 'ITEM_ADDED'; payload: { itemId: string; quantity: number } }
30
+ | { type: 'ITEM_REMOVED'; payload: { itemId: string } };
31
+
32
+ function handleEvent(event: AppEvent): void {
33
+ switch (event.type) {
34
+ case 'USER_LOGIN':
35
+ console.log(`User ${event.payload.userId} logged in`);
36
+ break;
37
+ case 'USER_LOGOUT':
38
+ console.log('User logged out');
39
+ break;
40
+ case 'ITEM_ADDED':
41
+ console.log(`Added ${event.payload.quantity} of ${event.payload.itemId}`);
42
+ break;
43
+ case 'ITEM_REMOVED':
44
+ console.log(`Removed ${event.payload.itemId}`);
45
+ break;
46
+ }
47
+ }
48
+
49
+ // Exhaustive check helper
50
+ function exhaustiveCheck(value: never): never {
51
+ throw new Error(`Unhandled value: ${JSON.stringify(value)}`);
52
+ }
53
+ ```
54
+
55
+ ## Zod for Runtime Validation
56
+
57
+ ```typescript
58
+ import { z } from 'zod';
59
+
60
+ // Define schema
61
+ const UserSchema = z.object({
62
+ id: z.string().uuid(),
63
+ name: z.string().min(1).max(100),
64
+ email: z.string().email(),
65
+ role: z.enum(['admin', 'user', 'viewer']),
66
+ age: z.number().int().min(0).max(150).optional(),
67
+ tags: z.array(z.string()).default([]),
68
+ });
69
+
70
+ // Infer TypeScript type from schema
71
+ type User = z.infer<typeof UserSchema>;
72
+
73
+ // Validate at runtime
74
+ function createUser(input: unknown): User {
75
+ return UserSchema.parse(input); // throws ZodError on failure
76
+ }
77
+
78
+ // Safe parse (no throw)
79
+ function validateUser(input: unknown): ApiResult<User> {
80
+ const result = UserSchema.safeParse(input);
81
+ if (result.success) {
82
+ return { status: 'success', data: result.data };
83
+ }
84
+ return {
85
+ status: 'error',
86
+ error: { code: 'VALIDATION', message: result.error.message },
87
+ };
88
+ }
89
+
90
+ // Schema composition
91
+ const CreateUserSchema = UserSchema.omit({ id: true });
92
+ const UpdateUserSchema = UserSchema.partial().required({ id: true });
93
+
94
+ // API request validation
95
+ const PaginationSchema = z.object({
96
+ page: z.coerce.number().int().min(1).default(1),
97
+ limit: z.coerce.number().int().min(1).max(100).default(20),
98
+ sort: z.enum(['asc', 'desc']).default('desc'),
99
+ });
100
+ ```
@@ -291,26 +291,7 @@ Model loading, compute units, conversion and optimization belong to the
291
291
  `DataScannerViewController` (iOS 16+) is a full-screen live camera that finds
292
292
  text and barcodes and highlights them.
293
293
 
294
- ```swift
295
- import UIKit
296
- import VisionKit
297
-
298
- @MainActor
299
- func presentTicketScanner(from host: UIViewController, delegate: DataScannerViewControllerDelegate) {
300
- guard DataScannerViewController.isSupported, DataScannerViewController.isAvailable else { return }
301
- let scanner = DataScannerViewController(
302
- recognizedDataTypes: [.text(languages: ["en"]), .barcode(symbologies: [.qr, .aztec])],
303
- qualityLevel: .balanced,
304
- recognizesMultipleItems: false,
305
- isHighFrameRateTrackingEnabled: true,
306
- isHighlightingEnabled: true
307
- )
308
- scanner.delegate = delegate
309
- host.present(scanner, animated: true) {
310
- try? scanner.startScanning()
311
- }
312
- }
313
- ```
294
+ Code: [VisionKit live scanning: DataScannerViewController](references/code-examples.md#visionkit-live-scanning-datascannerviewcontroller).
314
295
 
315
296
  `isSupported` checks the hardware (A12 Bionic or later); `isAvailable`
316
297
  additionally requires camera permission. In SwiftUI, wrap the controller in a
@@ -362,3 +343,4 @@ additionally requires camera permission. In SwiftUI, wrap the controller in a
362
343
  - https://developer.apple.com/documentation/visionkit
363
344
  - https://developer.apple.com/documentation/vision/recognizetextrequest
364
345
  - https://developer.apple.com/documentation/visionkit/datascannerviewcontroller
346
+ - [Code examples](references/code-examples.md): open for the full code behind VisionKit live scanning: DataScannerViewController.
@@ -0,0 +1,26 @@
1
+ # Vision Framework Code Examples
2
+
3
+ Full code samples for the SKILL.md sections that link here. The rules and the decision guidance stay in SKILL.md; each heading below matches the SKILL.md section the code belongs to.
4
+
5
+ ## VisionKit live scanning: DataScannerViewController
6
+
7
+ ```swift
8
+ import UIKit
9
+ import VisionKit
10
+
11
+ @MainActor
12
+ func presentTicketScanner(from host: UIViewController, delegate: DataScannerViewControllerDelegate) {
13
+ guard DataScannerViewController.isSupported, DataScannerViewController.isAvailable else { return }
14
+ let scanner = DataScannerViewController(
15
+ recognizedDataTypes: [.text(languages: ["en"]), .barcode(symbologies: [.qr, .aztec])],
16
+ qualityLevel: .balanced,
17
+ recognizesMultipleItems: false,
18
+ isHighFrameRateTrackingEnabled: true,
19
+ isHighlightingEnabled: true
20
+ )
21
+ scanner.delegate = delegate
22
+ host.present(scanner, animated: true) {
23
+ try? scanner.startScanning()
24
+ }
25
+ }
26
+ ```
@@ -164,181 +164,15 @@ watch(
164
164
 
165
165
  ## Composables (useXxx Pattern)
166
166
 
167
- ```typescript
168
- // composables/useFetch.ts
169
- import { ref, type Ref } from 'vue';
170
-
171
- interface UseFetchReturn<T> {
172
- data: Ref<T | null>;
173
- error: Ref<string | null>;
174
- isLoading: Ref<boolean>;
175
- execute: () => Promise<void>;
176
- }
177
-
178
- export function useFetch<T>(url: string | Ref<string>): UseFetchReturn<T> {
179
- const data = ref<T | null>(null) as Ref<T | null>;
180
- const error = ref<string | null>(null);
181
- const isLoading = ref(false);
182
-
183
- async function execute() {
184
- isLoading.value = true;
185
- error.value = null;
186
- try {
187
- const resolvedUrl = typeof url === 'string' ? url : url.value;
188
- const response = await fetch(resolvedUrl);
189
- if (!response.ok) throw new Error(`HTTP ${response.status}`);
190
- data.value = await response.json();
191
- } catch (e) {
192
- error.value = e instanceof Error ? e.message : 'Unknown error';
193
- } finally {
194
- isLoading.value = false;
195
- }
196
- }
197
-
198
- return { data, error, isLoading, execute };
199
- }
200
-
201
- // composables/useLocalStorage.ts
202
- import { ref, watch, type Ref } from 'vue';
203
-
204
- export function useLocalStorage<T>(key: string, defaultValue: T): Ref<T> {
205
- const stored = localStorage.getItem(key);
206
- const data = ref<T>(stored ? JSON.parse(stored) : defaultValue) as Ref<T>;
207
-
208
- watch(data, (newValue) => {
209
- localStorage.setItem(key, JSON.stringify(newValue));
210
- }, { deep: true });
211
-
212
- return data;
213
- }
214
-
215
- // composables/useDebounce.ts
216
- import { ref, watch, type Ref } from 'vue';
217
-
218
- export function useDebounce<T>(source: Ref<T>, delay = 300): Ref<T> {
219
- const debounced = ref(source.value) as Ref<T>;
220
- let timeout: ReturnType<typeof setTimeout>;
221
-
222
- watch(source, (newValue) => {
223
- clearTimeout(timeout);
224
- timeout = setTimeout(() => {
225
- debounced.value = newValue;
226
- }, delay);
227
- });
228
-
229
- return debounced;
230
- }
231
- ```
167
+ Code for this section: [Vue examples](references/vue-examples.md).
232
168
 
233
169
  ## Pinia State Management
234
170
 
235
- ```typescript
236
- // stores/auth.ts
237
- import { defineStore } from 'pinia';
238
- import { ref, computed } from 'vue';
239
-
240
- export const useAuthStore = defineStore('auth', () => {
241
- // State
242
- const user = ref<User | null>(null);
243
- const token = ref<string | null>(null);
244
-
245
- // Getters
246
- const isAuthenticated = computed(() => !!token.value);
247
- const displayName = computed(() => user.value?.name ?? 'Guest');
248
-
249
- // Actions
250
- async function login(credentials: { email: string; password: string }) {
251
- const response = await api.post('/auth/login', credentials);
252
- user.value = response.user;
253
- token.value = response.token;
254
- }
255
-
256
- function logout() {
257
- user.value = null;
258
- token.value = null;
259
- }
260
-
261
- return { user, token, isAuthenticated, displayName, login, logout };
262
- }, {
263
- persist: true, // pinia-plugin-persistedstate
264
- });
265
-
266
- // stores/cart.ts
267
- export const useCartStore = defineStore('cart', () => {
268
- const items = ref<CartItem[]>([]);
269
-
270
- const totalItems = computed(() =>
271
- items.value.reduce((sum, item) => sum + item.quantity, 0)
272
- );
273
-
274
- const totalPrice = computed(() =>
275
- items.value.reduce((sum, item) => sum + item.price * item.quantity, 0)
276
- );
277
-
278
- function addItem(product: Product) {
279
- const existing = items.value.find((i) => i.productId === product.id);
280
- if (existing) {
281
- existing.quantity++;
282
- } else {
283
- items.value.push({ productId: product.id, name: product.name, price: product.price, quantity: 1 });
284
- }
285
- }
286
-
287
- function removeItem(productId: string) {
288
- items.value = items.value.filter((i) => i.productId !== productId);
289
- }
290
-
291
- return { items, totalItems, totalPrice, addItem, removeItem };
292
- });
293
- ```
171
+ Code for this section: [Vue examples](references/vue-examples.md).
294
172
 
295
173
  ## Vue Router 4
296
174
 
297
- ```typescript
298
- // router/index.ts
299
- import { createRouter, createWebHistory } from 'vue-router';
300
- import type { RouteRecordRaw } from 'vue-router';
301
-
302
- const routes: RouteRecordRaw[] = [
303
- {
304
- path: '/',
305
- component: () => import('@/layouts/DefaultLayout.vue'),
306
- children: [
307
- { path: '', name: 'home', component: () => import('@/pages/HomePage.vue') },
308
- { path: 'about', name: 'about', component: () => import('@/pages/AboutPage.vue') },
309
- ],
310
- },
311
- {
312
- path: '/dashboard',
313
- component: () => import('@/layouts/DashboardLayout.vue'),
314
- meta: { requiresAuth: true },
315
- children: [
316
- { path: '', name: 'dashboard', component: () => import('@/pages/DashboardPage.vue') },
317
- { path: 'settings', name: 'settings', component: () => import('@/pages/SettingsPage.vue') },
318
- { path: 'users/:id', name: 'user-detail', component: () => import('@/pages/UserDetailPage.vue'), props: true },
319
- ],
320
- },
321
- { path: '/:pathMatch(.*)*', name: 'not-found', component: () => import('@/pages/NotFoundPage.vue') },
322
- ];
323
-
324
- const router = createRouter({
325
- history: createWebHistory(),
326
- routes,
327
- scrollBehavior(to, from, savedPosition) {
328
- return savedPosition ?? { top: 0 };
329
- },
330
- });
331
-
332
- // Navigation guard
333
- router.beforeEach((to, from) => {
334
- const auth = useAuthStore();
335
- if (to.meta.requiresAuth && !auth.isAuthenticated) {
336
- return { name: 'login', query: { redirect: to.fullPath } };
337
- }
338
- });
339
-
340
- export default router;
341
- ```
175
+ Code for this section: [Vue examples](references/vue-examples.md).
342
176
 
343
177
  ## Do's
344
178
 
@@ -372,3 +206,7 @@ export default router;
372
206
  | Prop mutation warning | Modifying prop directly | Use `defineModel` or emit event with new value |
373
207
  | Template ref is null | Accessed before mount | Use `onMounted` hook or optional chaining |
374
208
  | Pinia state lost on refresh | No persistence plugin | Add `pinia-plugin-persistedstate` |
209
+
210
+ ## References
211
+
212
+ - [Vue examples](references/vue-examples.md): open when writing a composable, a Pinia store or router configuration and guards.
@@ -0,0 +1,187 @@
1
+ # Vue examples
2
+
3
+ <!-- toc -->
4
+ - [Composables (useXxx Pattern)](#composables-usexxx-pattern)
5
+ - [Pinia State Management](#pinia-state-management)
6
+ - [Vue Router 4](#vue-router-4)
7
+ <!-- /toc -->
8
+
9
+ Code for composables, Pinia stores and Vue Router 4. SKILL.md keeps the core concepts, script setup, reactivity and watcher rules.
10
+
11
+ ## Composables (useXxx Pattern)
12
+
13
+ ```typescript
14
+ // composables/useFetch.ts
15
+ import { ref, type Ref } from 'vue';
16
+
17
+ interface UseFetchReturn<T> {
18
+ data: Ref<T | null>;
19
+ error: Ref<string | null>;
20
+ isLoading: Ref<boolean>;
21
+ execute: () => Promise<void>;
22
+ }
23
+
24
+ export function useFetch<T>(url: string | Ref<string>): UseFetchReturn<T> {
25
+ const data = ref<T | null>(null) as Ref<T | null>;
26
+ const error = ref<string | null>(null);
27
+ const isLoading = ref(false);
28
+
29
+ async function execute() {
30
+ isLoading.value = true;
31
+ error.value = null;
32
+ try {
33
+ const resolvedUrl = typeof url === 'string' ? url : url.value;
34
+ const response = await fetch(resolvedUrl);
35
+ if (!response.ok) throw new Error(`HTTP ${response.status}`);
36
+ data.value = await response.json();
37
+ } catch (e) {
38
+ error.value = e instanceof Error ? e.message : 'Unknown error';
39
+ } finally {
40
+ isLoading.value = false;
41
+ }
42
+ }
43
+
44
+ return { data, error, isLoading, execute };
45
+ }
46
+
47
+ // composables/useLocalStorage.ts
48
+ import { ref, watch, type Ref } from 'vue';
49
+
50
+ export function useLocalStorage<T>(key: string, defaultValue: T): Ref<T> {
51
+ const stored = localStorage.getItem(key);
52
+ const data = ref<T>(stored ? JSON.parse(stored) : defaultValue) as Ref<T>;
53
+
54
+ watch(data, (newValue) => {
55
+ localStorage.setItem(key, JSON.stringify(newValue));
56
+ }, { deep: true });
57
+
58
+ return data;
59
+ }
60
+
61
+ // composables/useDebounce.ts
62
+ import { ref, watch, type Ref } from 'vue';
63
+
64
+ export function useDebounce<T>(source: Ref<T>, delay = 300): Ref<T> {
65
+ const debounced = ref(source.value) as Ref<T>;
66
+ let timeout: ReturnType<typeof setTimeout>;
67
+
68
+ watch(source, (newValue) => {
69
+ clearTimeout(timeout);
70
+ timeout = setTimeout(() => {
71
+ debounced.value = newValue;
72
+ }, delay);
73
+ });
74
+
75
+ return debounced;
76
+ }
77
+ ```
78
+
79
+ ## Pinia State Management
80
+
81
+ ```typescript
82
+ // stores/auth.ts
83
+ import { defineStore } from 'pinia';
84
+ import { ref, computed } from 'vue';
85
+
86
+ export const useAuthStore = defineStore('auth', () => {
87
+ // State
88
+ const user = ref<User | null>(null);
89
+ const token = ref<string | null>(null);
90
+
91
+ // Getters
92
+ const isAuthenticated = computed(() => !!token.value);
93
+ const displayName = computed(() => user.value?.name ?? 'Guest');
94
+
95
+ // Actions
96
+ async function login(credentials: { email: string; password: string }) {
97
+ const response = await api.post('/auth/login', credentials);
98
+ user.value = response.user;
99
+ token.value = response.token;
100
+ }
101
+
102
+ function logout() {
103
+ user.value = null;
104
+ token.value = null;
105
+ }
106
+
107
+ return { user, token, isAuthenticated, displayName, login, logout };
108
+ }, {
109
+ persist: true, // pinia-plugin-persistedstate
110
+ });
111
+
112
+ // stores/cart.ts
113
+ export const useCartStore = defineStore('cart', () => {
114
+ const items = ref<CartItem[]>([]);
115
+
116
+ const totalItems = computed(() =>
117
+ items.value.reduce((sum, item) => sum + item.quantity, 0)
118
+ );
119
+
120
+ const totalPrice = computed(() =>
121
+ items.value.reduce((sum, item) => sum + item.price * item.quantity, 0)
122
+ );
123
+
124
+ function addItem(product: Product) {
125
+ const existing = items.value.find((i) => i.productId === product.id);
126
+ if (existing) {
127
+ existing.quantity++;
128
+ } else {
129
+ items.value.push({ productId: product.id, name: product.name, price: product.price, quantity: 1 });
130
+ }
131
+ }
132
+
133
+ function removeItem(productId: string) {
134
+ items.value = items.value.filter((i) => i.productId !== productId);
135
+ }
136
+
137
+ return { items, totalItems, totalPrice, addItem, removeItem };
138
+ });
139
+ ```
140
+
141
+ ## Vue Router 4
142
+
143
+ ```typescript
144
+ // router/index.ts
145
+ import { createRouter, createWebHistory } from 'vue-router';
146
+ import type { RouteRecordRaw } from 'vue-router';
147
+
148
+ const routes: RouteRecordRaw[] = [
149
+ {
150
+ path: '/',
151
+ component: () => import('@/layouts/DefaultLayout.vue'),
152
+ children: [
153
+ { path: '', name: 'home', component: () => import('@/pages/HomePage.vue') },
154
+ { path: 'about', name: 'about', component: () => import('@/pages/AboutPage.vue') },
155
+ ],
156
+ },
157
+ {
158
+ path: '/dashboard',
159
+ component: () => import('@/layouts/DashboardLayout.vue'),
160
+ meta: { requiresAuth: true },
161
+ children: [
162
+ { path: '', name: 'dashboard', component: () => import('@/pages/DashboardPage.vue') },
163
+ { path: 'settings', name: 'settings', component: () => import('@/pages/SettingsPage.vue') },
164
+ { path: 'users/:id', name: 'user-detail', component: () => import('@/pages/UserDetailPage.vue'), props: true },
165
+ ],
166
+ },
167
+ { path: '/:pathMatch(.*)*', name: 'not-found', component: () => import('@/pages/NotFoundPage.vue') },
168
+ ];
169
+
170
+ const router = createRouter({
171
+ history: createWebHistory(),
172
+ routes,
173
+ scrollBehavior(to, from, savedPosition) {
174
+ return savedPosition ?? { top: 0 };
175
+ },
176
+ });
177
+
178
+ // Navigation guard
179
+ router.beforeEach((to, from) => {
180
+ const auth = useAuthStore();
181
+ if (to.meta.requiresAuth && !auth.isAuthenticated) {
182
+ return { name: 'login', query: { redirect: to.fullPath } };
183
+ }
184
+ });
185
+
186
+ export default router;
187
+ ```