@leejungkiin/awkit 1.7.1 → 1.7.4

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 (245) hide show
  1. package/bin/awk.js +576 -84
  2. package/core/CLAUDE.md +1 -1
  3. package/core/GEMINI.md +148 -167
  4. package/core/GEMINI.md.bak +149 -116
  5. package/core/skill-runtime-manifest.json +3 -0
  6. package/docs/Claude Fable 5.md +3826 -0
  7. package/docs/android_kotlin_system_instruction.md +210 -0
  8. package/docs/brainstorm_ponytail_integration.md +146 -0
  9. package/docs/brainstorm_smart_setup.md +113 -0
  10. package/docs/deep-research-report (1).md +293 -0
  11. package/docs/history/GEMINI.v1.md +135 -0
  12. package/docs/history/brainstorm_antigravity_unified_architecture.v1.md +105 -0
  13. package/docs/history/implementation_plan.v1.md +58 -0
  14. package/package.json +4 -1
  15. package/scripts/artifact-storage.js +130 -0
  16. package/scripts/automation-gate.js +35 -2
  17. package/scripts/claude-plan.js +76 -0
  18. package/scripts/dependency-manager.js +210 -0
  19. package/scripts/exec-rtk.js +11 -5
  20. package/scripts/i18n-helper.js +381 -0
  21. package/scripts/multi-model-pipeline.js +144 -0
  22. package/skill-packs/mobile-ios/pack.json +4 -2
  23. package/skill-packs/reverse-engineering/pack.json +1 -0
  24. package/skills/CATALOG.md +20 -0
  25. package/skills/GEMINI.md +9 -1
  26. package/skills/TRIGGER_INDEX.md +10 -0
  27. package/skills/ai-music/SKILL.md +275 -0
  28. package/skills/android-re-analyzer/SKILL.md +238 -0
  29. package/skills/android-re-analyzer/references/api-extraction-patterns.md +119 -0
  30. package/skills/android-re-analyzer/references/call-flow-analysis.md +176 -0
  31. package/skills/android-re-analyzer/references/fernflower-usage.md +115 -0
  32. package/skills/android-re-analyzer/references/jadx-usage.md +116 -0
  33. package/skills/android-re-analyzer/references/setup-guide.md +221 -0
  34. package/skills/android-re-analyzer/scripts/check-deps.sh +129 -0
  35. package/skills/android-re-analyzer/scripts/decompile.sh +375 -0
  36. package/skills/android-re-analyzer/scripts/find-api-calls.sh +118 -0
  37. package/skills/android-re-analyzer/scripts/install-dep.sh +448 -0
  38. package/skills/animal-island-ui-style/SKILL.md +1450 -0
  39. package/skills/app-store-review-agent/SKILL.md +164 -0
  40. package/skills/app-store-review-agent/references/guidelines/README.md +154 -0
  41. package/skills/app-store-review-agent/references/guidelines/by-app-type/ai_apps.md +37 -0
  42. package/skills/app-store-review-agent/references/guidelines/by-app-type/all_apps.md +50 -0
  43. package/skills/app-store-review-agent/references/guidelines/by-app-type/crypto_finance.md +31 -0
  44. package/skills/app-store-review-agent/references/guidelines/by-app-type/games.md +31 -0
  45. package/skills/app-store-review-agent/references/guidelines/by-app-type/health_fitness.md +31 -0
  46. package/skills/app-store-review-agent/references/guidelines/by-app-type/kids.md +27 -0
  47. package/skills/app-store-review-agent/references/guidelines/by-app-type/macos.md +38 -0
  48. package/skills/app-store-review-agent/references/guidelines/by-app-type/social_ugc.md +32 -0
  49. package/skills/app-store-review-agent/references/guidelines/by-app-type/subscription_iap.md +34 -0
  50. package/skills/app-store-review-agent/references/guidelines/by-app-type/vpn.md +18 -0
  51. package/skills/app-store-review-agent/references/rules/design/minimum_functionality.md +96 -0
  52. package/skills/app-store-review-agent/references/rules/design/sign_in_with_apple.md +54 -0
  53. package/skills/app-store-review-agent/references/rules/entitlements/unused_entitlements.md +83 -0
  54. package/skills/app-store-review-agent/references/rules/metadata/accurate_metadata.md +54 -0
  55. package/skills/app-store-review-agent/references/rules/metadata/apple_trademark.md +99 -0
  56. package/skills/app-store-review-agent/references/rules/metadata/china_storefront.md +72 -0
  57. package/skills/app-store-review-agent/references/rules/metadata/competitor_terms.md +56 -0
  58. package/skills/app-store-review-agent/references/rules/metadata/subscription_metadata.md +81 -0
  59. package/skills/app-store-review-agent/references/rules/privacy/privacy_manifest.md +84 -0
  60. package/skills/app-store-review-agent/references/rules/privacy/unnecessary_data.md +60 -0
  61. package/skills/app-store-review-agent/references/rules/subscription/misleading_pricing.md +63 -0
  62. package/skills/app-store-review-agent/references/rules/subscription/missing_tos_pp.md +54 -0
  63. package/skills/awf-ponytail/SKILL.md +91 -0
  64. package/skills/awf-ponytail-review/SKILL.md +67 -0
  65. package/skills/awf-session-restore/SKILL.md +3 -3
  66. package/skills/brainstorm-agent/SKILL.md +11 -2
  67. package/skills/brainstorm-agent/templates/brief-template.md +8 -0
  68. package/skills/claude-planner/SKILL.md +47 -0
  69. package/skills/code-review/SKILL.md +87 -0
  70. package/skills/expo-game-development/SKILL.md +163 -0
  71. package/skills/flutter/LICENSE.txt +202 -0
  72. package/skills/flutter/SKILL.md +127 -0
  73. package/skills/flutter-project-creater/LICENSE.txt +202 -0
  74. package/skills/flutter-project-creater/SKILL.md +106 -0
  75. package/skills/game-developer/SKILL.md +163 -0
  76. package/skills/game-developer/references/ecs-patterns.md +501 -0
  77. package/skills/game-developer/references/multiplayer-networking.md +475 -0
  78. package/skills/game-developer/references/performance-optimization.md +422 -0
  79. package/skills/game-developer/references/unity-patterns.md +271 -0
  80. package/skills/game-developer/references/unreal-cpp.md +352 -0
  81. package/skills/generate-gui-assets/SKILL.md +305 -0
  82. package/skills/generate-gui-assets/agents/openai.yaml +4 -0
  83. package/skills/generate-gui-assets/references/catalog-schema.md +58 -0
  84. package/skills/generate-gui-assets/references/extraction-techniques.md +21 -0
  85. package/skills/generate-gui-assets/references/prompt-patterns.md +58 -0
  86. package/skills/generate-gui-assets/scripts/__pycache__/clean_chroma_edges.cpython-311.pyc +0 -0
  87. package/skills/generate-gui-assets/scripts/build_gui_contact_sheet.py +51 -0
  88. package/skills/generate-gui-assets/scripts/clean_chroma_edges.py +262 -0
  89. package/skills/generate-gui-assets/scripts/copy_approved_icons.py +64 -0
  90. package/skills/generate-gui-assets/scripts/prepare_gui_asset_run.py +91 -0
  91. package/skills/generate-gui-assets/scripts/suggest_grid_options.py +63 -0
  92. package/skills/generate-gui-assets/scripts/validate_gui_catalog.py +50 -0
  93. package/skills/godot-game-development/SKILL.md +142 -0
  94. package/skills/hatch-pet/LICENSE.txt +201 -0
  95. package/skills/hatch-pet/SKILL.md +420 -0
  96. package/skills/hatch-pet/agents/openai.yaml +4 -0
  97. package/skills/hatch-pet/references/animation-rows.md +29 -0
  98. package/skills/hatch-pet/references/codex-pet-contract.md +35 -0
  99. package/skills/hatch-pet/references/qa-rubric.md +60 -0
  100. package/skills/hatch-pet/scripts/__pycache__/clean_chroma_edges.cpython-311.pyc +0 -0
  101. package/skills/hatch-pet/scripts/clean_chroma_edges.py +262 -0
  102. package/skills/hatch-pet/scripts/compose_atlas.py +150 -0
  103. package/skills/hatch-pet/scripts/derive_running_left_from_running_right.py +143 -0
  104. package/skills/hatch-pet/scripts/extract_strip_frames.py +323 -0
  105. package/skills/hatch-pet/scripts/finalize_pet_run.py +382 -0
  106. package/skills/hatch-pet/scripts/generate_pet_images.py +287 -0
  107. package/skills/hatch-pet/scripts/inspect_frames.py +246 -0
  108. package/skills/hatch-pet/scripts/make_contact_sheet.py +96 -0
  109. package/skills/hatch-pet/scripts/package_custom_pet.py +108 -0
  110. package/skills/hatch-pet/scripts/pet_job_status.py +117 -0
  111. package/skills/hatch-pet/scripts/prepare_pet_run.py +673 -0
  112. package/skills/hatch-pet/scripts/queue_pet_repairs.py +172 -0
  113. package/skills/hatch-pet/scripts/record_imagegen_result.py +250 -0
  114. package/skills/hatch-pet/scripts/render_animation_videos.py +134 -0
  115. package/skills/hatch-pet/scripts/render_animation_videos.sh +5 -0
  116. package/skills/hatch-pet/scripts/validate_atlas.py +139 -0
  117. package/skills/i18n-orchestrator/SKILL.md +37 -0
  118. package/skills/ios-simulator-skill/SKILL.md +390 -0
  119. package/skills/ios-simulator-skill/scripts/accessibility_audit.py +300 -0
  120. package/skills/ios-simulator-skill/scripts/app_launcher.py +326 -0
  121. package/skills/ios-simulator-skill/scripts/app_state_capture.py +400 -0
  122. package/skills/ios-simulator-skill/scripts/appearance.py +385 -0
  123. package/skills/ios-simulator-skill/scripts/build_and_test.py +348 -0
  124. package/skills/ios-simulator-skill/scripts/clipboard.py +103 -0
  125. package/skills/ios-simulator-skill/scripts/common/__init__.py +61 -0
  126. package/skills/ios-simulator-skill/scripts/common/cache_utils.py +289 -0
  127. package/skills/ios-simulator-skill/scripts/common/device_utils.py +462 -0
  128. package/skills/ios-simulator-skill/scripts/common/env_config.py +35 -0
  129. package/skills/ios-simulator-skill/scripts/common/hang_pipeline.py +862 -0
  130. package/skills/ios-simulator-skill/scripts/common/hang_sessions.py +490 -0
  131. package/skills/ios-simulator-skill/scripts/common/idb_utils.py +180 -0
  132. package/skills/ios-simulator-skill/scripts/common/screenshot_utils.py +338 -0
  133. package/skills/ios-simulator-skill/scripts/container.py +668 -0
  134. package/skills/ios-simulator-skill/scripts/gesture.py +394 -0
  135. package/skills/ios-simulator-skill/scripts/hang_watcher.py +1533 -0
  136. package/skills/ios-simulator-skill/scripts/keyboard.py +391 -0
  137. package/skills/ios-simulator-skill/scripts/localization_audit.py +483 -0
  138. package/skills/ios-simulator-skill/scripts/location.py +467 -0
  139. package/skills/ios-simulator-skill/scripts/log_monitor.py +493 -0
  140. package/skills/ios-simulator-skill/scripts/model_inspector.py +645 -0
  141. package/skills/ios-simulator-skill/scripts/navigator.py +461 -0
  142. package/skills/ios-simulator-skill/scripts/privacy_manager.py +310 -0
  143. package/skills/ios-simulator-skill/scripts/push_notification.py +240 -0
  144. package/skills/ios-simulator-skill/scripts/screen_mapper.py +296 -0
  145. package/skills/ios-simulator-skill/scripts/sim_health_check.sh +245 -0
  146. package/skills/ios-simulator-skill/scripts/sim_list.py +299 -0
  147. package/skills/ios-simulator-skill/scripts/simctl_boot.py +312 -0
  148. package/skills/ios-simulator-skill/scripts/simctl_create.py +316 -0
  149. package/skills/ios-simulator-skill/scripts/simctl_delete.py +357 -0
  150. package/skills/ios-simulator-skill/scripts/simctl_erase.py +351 -0
  151. package/skills/ios-simulator-skill/scripts/simctl_shutdown.py +290 -0
  152. package/skills/ios-simulator-skill/scripts/simulator_selector.py +375 -0
  153. package/skills/ios-simulator-skill/scripts/status_bar.py +250 -0
  154. package/skills/ios-simulator-skill/scripts/test_recorder.py +323 -0
  155. package/skills/ios-simulator-skill/scripts/visual_diff.py +235 -0
  156. package/skills/ios-simulator-skill/scripts/xcode/__init__.py +13 -0
  157. package/skills/ios-simulator-skill/scripts/xcode/builder.py +397 -0
  158. package/skills/ios-simulator-skill/scripts/xcode/cache.py +204 -0
  159. package/skills/ios-simulator-skill/scripts/xcode/config.py +178 -0
  160. package/skills/ios-simulator-skill/scripts/xcode/reporter.py +343 -0
  161. package/skills/ios-simulator-skill/scripts/xcode/xcresult.py +451 -0
  162. package/skills/ios-visual-qa-strategist/SKILL.md +111 -0
  163. package/skills/ios-visual-qa-strategist/agents/openai.yaml +4 -0
  164. package/skills/ios-visual-qa-strategist/references/ios-tool-selection.md +61 -0
  165. package/skills/ios-visual-qa-strategist/references/minimal-capture-policy.md +56 -0
  166. package/skills/ios-visual-qa-strategist/references/visual-reasoning-heuristics.md +53 -0
  167. package/skills/orchestrator/SKILL.md +0 -20
  168. package/skills/persistent-storage/SKILL.md +55 -0
  169. package/skills/short-maker/SKILL.md +23 -0
  170. package/skills/short-maker/scripts/effects.js +56 -0
  171. package/skills/short-maker/scripts/shortmaker-bridge.js +332 -0
  172. package/skills/short-maker/scripts/videomix.js +601 -0
  173. package/skills/short-maker/templates/hyperframes/cinematic-character.template.html +172 -0
  174. package/skills/short-maker/templates/hyperframes/index.template.html +194 -0
  175. package/skills/smali-to-kotlin/SKILL.md +128 -0
  176. package/skills/smali-to-kotlin/examples/getting-started/tech-stack.md +58 -0
  177. package/skills/smali-to-kotlin/examples/pipeline/data-ui-parity.md +118 -0
  178. package/skills/smali-to-kotlin/examples/pipeline/scanner-and-bootstrap.md +106 -0
  179. package/skills/smali-to-kotlin/library-patterns.md +189 -0
  180. package/skills/smali-to-kotlin/phase-0-discovery.md +128 -0
  181. package/skills/smali-to-kotlin/phase-1-architecture.md +166 -0
  182. package/skills/smali-to-kotlin/phase-2-blueprint-ui.md +347 -0
  183. package/skills/smali-to-kotlin/phase-2-blueprint.md +228 -0
  184. package/skills/smali-to-kotlin/phase-3-build.md +248 -0
  185. package/skills/smali-to-kotlin/phase-3-logic-build.md +268 -0
  186. package/skills/smali-to-kotlin/smali-reading-guide.md +310 -0
  187. package/skills/smali-to-kotlin/templates/app-map.md +101 -0
  188. package/skills/smali-to-kotlin/templates/architecture.md +142 -0
  189. package/skills/smali-to-kotlin/templates/blueprint.md +145 -0
  190. package/skills/spec-gate/SKILL.md +6 -2
  191. package/skills/symphony-enforcer/SKILL.md +8 -0
  192. package/skills/symphony-enforcer/examples/mindful-stop.md +2 -0
  193. package/skills/symphony-enforcer/examples/three-phase.md +16 -0
  194. package/skills/symphony-enforcer/examples/trigger-points.md +7 -1
  195. package/skills/unity-game-development/SKILL.md +231 -0
  196. package/skills/video-edit/SKILL.md +36 -0
  197. package/skills/video-edit/scripts/video_edit.py +324 -0
  198. package/templates/project-identity/android.json +2 -2
  199. package/templates/project-identity/backend-nestjs.json +2 -2
  200. package/templates/project-identity/expo.json +2 -2
  201. package/templates/project-identity/ios.json +2 -2
  202. package/templates/project-identity/web-nextjs.json +2 -2
  203. package/templates/setup-mapping.json +48 -0
  204. package/templates/specs/design-template.md +161 -71
  205. package/templates/specs/requirements-template.md +65 -133
  206. package/templates/specs/task-spec-template.xml +3 -0
  207. package/workflows/_uncategorized/critic.md +40 -0
  208. package/workflows/_uncategorized/git-rebase-flow.md +81 -0
  209. package/workflows/_uncategorized/image-gen.md +118 -0
  210. package/workflows/_uncategorized/multi-model-pipeline.md +60 -0
  211. package/workflows/_uncategorized/pixel-gen.md +86 -0
  212. package/workflows/_uncategorized/pixel-setup.md +90 -0
  213. package/workflows/_uncategorized/ponytail-review.md +59 -0
  214. package/workflows/_uncategorized/reverse-android-build.md +222 -0
  215. package/workflows/_uncategorized/reverse-android-design.md +139 -0
  216. package/workflows/_uncategorized/reverse-android-discover.md +150 -0
  217. package/workflows/_uncategorized/reverse-android-scan.md +158 -0
  218. package/workflows/_uncategorized/reverse-android.md +143 -0
  219. package/workflows/_uncategorized/reverse-ios-build.md +240 -0
  220. package/workflows/_uncategorized/reverse-ios-design.md +112 -0
  221. package/workflows/_uncategorized/reverse-ios-discover.md +120 -0
  222. package/workflows/_uncategorized/reverse-ios-scan.md +155 -0
  223. package/workflows/_uncategorized/reverse-ios.md +152 -0
  224. package/workflows/_uncategorized/safety-router.md +34 -0
  225. package/workflows/_uncategorized/teach.md +89 -0
  226. package/workflows/_uncategorized/verify-ui.md +53 -0
  227. package/workflows/_uncategorized/visualize-screenshots.md +34 -0
  228. package/workflows/ads/ads-analyst.md +201 -0
  229. package/workflows/ads/ads-audit.md +106 -0
  230. package/workflows/ads/ads-optimize.md +97 -0
  231. package/workflows/ads/ads-targeting.md +241 -0
  232. package/workflows/ads/adsExpert.md +160 -0
  233. package/workflows/ads/smali-ads-config.md +400 -0
  234. package/workflows/ads/smali-ads-flow.md +331 -0
  235. package/workflows/ads/smali-ads-interstitial.md +377 -0
  236. package/workflows/ads/smali-ads-native.md +382 -0
  237. package/workflows/context/teach.md +89 -0
  238. package/workflows/gitnexus.md +8 -8
  239. package/workflows/lifecycle/brainstorm.md +43 -0
  240. package/workflows/lifecycle/code.md +5 -0
  241. package/workflows/lifecycle/init.md +23 -5
  242. package/workflows/lifecycle/multi-model-pipeline.md +60 -0
  243. package/workflows/quality/ponytail-review.md +59 -0
  244. package/workflows/roles/critic.md +40 -0
  245. package/workflows/roles/safety-router.md +34 -0
@@ -0,0 +1,348 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Build and Test Automation for Xcode Projects
4
+
5
+ Ultra token-efficient build automation with progressive disclosure via xcresult bundles.
6
+
7
+ Features:
8
+ - Minimal default output (5-10 tokens)
9
+ - Progressive disclosure for error/warning/log details
10
+ - Native xcresult bundle support
11
+ - Clean modular architecture
12
+
13
+ Usage Examples:
14
+ # Build (minimal output)
15
+ python scripts/build_and_test.py --project MyApp.xcodeproj
16
+ # Output: Build: SUCCESS (0 errors, 3 warnings) [xcresult-20251018-143052]
17
+
18
+ # Get error details
19
+ python scripts/build_and_test.py --get-errors xcresult-20251018-143052
20
+
21
+ # Get warnings
22
+ python scripts/build_and_test.py --get-warnings xcresult-20251018-143052
23
+
24
+ # Get build log
25
+ python scripts/build_and_test.py --get-log xcresult-20251018-143052
26
+
27
+ # Get everything as JSON
28
+ python scripts/build_and_test.py --get-all xcresult-20251018-143052 --json
29
+
30
+ # List recent builds
31
+ python scripts/build_and_test.py --list-xcresults
32
+
33
+ # Verbose mode (for debugging)
34
+ python scripts/build_and_test.py --project MyApp.xcodeproj --verbose
35
+ """
36
+
37
+ import argparse
38
+ import sys
39
+ from pathlib import Path
40
+
41
+ # Import our modular components
42
+ from common.env_config import env_int
43
+
44
+ from xcode import BuildRunner, OutputFormatter, XCResultCache, XCResultParser
45
+
46
+ BUILD_LOG_PREVIEW_CHARS = env_int("IOS_SIM_BUILD_LOG_PREVIEW", 4000)
47
+ BUILD_JSON_CAP = env_int("IOS_SIM_BUILD_JSON_CAP", 50)
48
+
49
+
50
+ def main():
51
+ """Main entry point."""
52
+ parser = argparse.ArgumentParser(
53
+ description="Build and test Xcode projects with progressive disclosure",
54
+ formatter_class=argparse.RawDescriptionHelpFormatter,
55
+ epilog="""
56
+ Examples:
57
+ # Build project (minimal output)
58
+ python scripts/build_and_test.py --project MyApp.xcodeproj
59
+
60
+ # Run tests
61
+ python scripts/build_and_test.py --project MyApp.xcodeproj --test
62
+
63
+ # Get error details from previous build
64
+ python scripts/build_and_test.py --get-errors xcresult-20251018-143052
65
+
66
+ # Get all details as JSON
67
+ python scripts/build_and_test.py --get-all xcresult-20251018-143052 --json
68
+
69
+ # List recent builds
70
+ python scripts/build_and_test.py --list-xcresults
71
+ """,
72
+ )
73
+
74
+ # Build/test mode arguments
75
+ build_group = parser.add_argument_group("Build/Test Options")
76
+ project_group = build_group.add_mutually_exclusive_group()
77
+ project_group.add_argument("--project", help="Path to .xcodeproj file")
78
+ project_group.add_argument("--workspace", help="Path to .xcworkspace file")
79
+
80
+ build_group.add_argument("--scheme", help="Build scheme (auto-detected if not specified)")
81
+ build_group.add_argument(
82
+ "--configuration",
83
+ default="Debug",
84
+ help="Build configuration (default: Debug). Accepts any valid Xcode configuration.",
85
+ )
86
+ build_group.add_argument("--simulator", help="Simulator name (default: iPhone 15)")
87
+ build_group.add_argument("--clean", action="store_true", help="Clean before building")
88
+ build_group.add_argument("--test", action="store_true", help="Run tests")
89
+ build_group.add_argument("--suite", help="Specific test suite to run")
90
+
91
+ # Progressive disclosure arguments
92
+ disclosure_group = parser.add_argument_group("Progressive Disclosure Options")
93
+ disclosure_group.add_argument(
94
+ "--get-errors", metavar="XCRESULT_ID", help="Get error details from xcresult"
95
+ )
96
+ disclosure_group.add_argument(
97
+ "--get-warnings", metavar="XCRESULT_ID", help="Get warning details from xcresult"
98
+ )
99
+ disclosure_group.add_argument(
100
+ "--get-log", metavar="XCRESULT_ID", help="Get build log from xcresult"
101
+ )
102
+ disclosure_group.add_argument(
103
+ "--get-all", metavar="XCRESULT_ID", help="Get all details from xcresult"
104
+ )
105
+ disclosure_group.add_argument(
106
+ "--list-xcresults", action="store_true", help="List recent xcresult bundles"
107
+ )
108
+
109
+ # Output options
110
+ output_group = parser.add_argument_group("Output Options")
111
+ output_group.add_argument("--verbose", action="store_true", help="Show detailed output")
112
+ output_group.add_argument("--json", action="store_true", help="Output as JSON")
113
+
114
+ args = parser.parse_args()
115
+
116
+ # Initialize cache
117
+ cache = XCResultCache()
118
+
119
+ # Handle list mode
120
+ if args.list_xcresults:
121
+ xcresults = cache.list()
122
+ if args.json:
123
+ import json
124
+
125
+ print(json.dumps(xcresults, indent=2))
126
+ elif not xcresults:
127
+ print("No xcresult bundles found")
128
+ else:
129
+ print(f"Recent XCResult bundles ({len(xcresults)}):")
130
+ print()
131
+ for xc in xcresults:
132
+ print(f" {xc['id']}")
133
+ print(f" Created: {xc['created']}")
134
+ print(f" Size: {xc['size_mb']} MB")
135
+ print()
136
+ return 0
137
+
138
+ # Handle retrieval modes
139
+ xcresult_id = args.get_errors or args.get_warnings or args.get_log or args.get_all
140
+
141
+ if xcresult_id:
142
+ xcresult_path = cache.get_path(xcresult_id)
143
+
144
+ if not xcresult_path or not xcresult_path.exists():
145
+ print(f"Error: XCResult bundle not found: {xcresult_id}", file=sys.stderr)
146
+ print("Use --list-xcresults to see available bundles", file=sys.stderr)
147
+ return 1
148
+
149
+ # Load cached stderr for progressive disclosure
150
+ cached_stderr = cache.get_stderr(xcresult_id)
151
+ parser = XCResultParser(xcresult_path, stderr=cached_stderr)
152
+
153
+ # Get errors
154
+ if args.get_errors:
155
+ errors = parser.get_errors()
156
+ if args.json:
157
+ import json
158
+
159
+ print(json.dumps(errors, indent=2))
160
+ else:
161
+ print(OutputFormatter.format_errors(errors))
162
+ return 0
163
+
164
+ # Get warnings
165
+ if args.get_warnings:
166
+ warnings = parser.get_warnings()
167
+ if args.json:
168
+ import json
169
+
170
+ print(json.dumps(warnings, indent=2))
171
+ else:
172
+ print(OutputFormatter.format_warnings(warnings))
173
+ return 0
174
+
175
+ # Get log
176
+ if args.get_log:
177
+ log = parser.get_build_log()
178
+ if log:
179
+ print(OutputFormatter.format_log(log))
180
+ else:
181
+ print("No build log available", file=sys.stderr)
182
+ return 1
183
+ return 0
184
+
185
+ # Get all
186
+ if args.get_all:
187
+ error_count, warning_count = parser.count_issues()
188
+ errors = parser.get_errors()
189
+ warnings = parser.get_warnings()
190
+ build_log = parser.get_build_log()
191
+
192
+ if args.json:
193
+ import json
194
+
195
+ data = {
196
+ "xcresult_id": xcresult_id,
197
+ "error_count": error_count,
198
+ "warning_count": warning_count,
199
+ "errors": errors,
200
+ "warnings": warnings,
201
+ "log_preview": build_log[:BUILD_LOG_PREVIEW_CHARS] if build_log else None,
202
+ }
203
+ print(json.dumps(data, indent=2))
204
+ else:
205
+ print(f"XCResult: {xcresult_id}")
206
+ print(f"Errors: {error_count}, Warnings: {warning_count}")
207
+ print()
208
+ if errors:
209
+ print(OutputFormatter.format_errors(errors, limit=10))
210
+ print()
211
+ if warnings:
212
+ print(OutputFormatter.format_warnings(warnings, limit=10))
213
+ print()
214
+ if build_log:
215
+ print("Build Log (last 30 lines):")
216
+ print(OutputFormatter.format_log(build_log, lines=30))
217
+ return 0
218
+
219
+ # Build/test mode
220
+ if not args.project and not args.workspace:
221
+ # Try to auto-detect in current directory
222
+ cwd = Path.cwd()
223
+ projects = list(cwd.glob("*.xcodeproj"))
224
+ workspaces = list(cwd.glob("*.xcworkspace"))
225
+
226
+ if workspaces:
227
+ args.workspace = str(workspaces[0])
228
+ elif projects:
229
+ args.project = str(projects[0])
230
+ else:
231
+ parser.error("No project or workspace specified and none found in current directory")
232
+
233
+ # Initialize builder
234
+ builder = BuildRunner(
235
+ project_path=args.project,
236
+ workspace_path=args.workspace,
237
+ scheme=args.scheme,
238
+ configuration=args.configuration,
239
+ simulator=args.simulator,
240
+ cache=cache,
241
+ )
242
+
243
+ # Execute build or test
244
+ if args.test:
245
+ success, xcresult_id, stderr = builder.test(test_suite=args.suite)
246
+ else:
247
+ success, xcresult_id, stderr = builder.build(clean=args.clean)
248
+
249
+ if not xcresult_id and not stderr:
250
+ print("Error: Build/test failed without creating xcresult or error output", file=sys.stderr)
251
+ return 1
252
+
253
+ # Save stderr to cache for progressive disclosure
254
+ if xcresult_id and stderr:
255
+ cache.save_stderr(xcresult_id, stderr)
256
+
257
+ # Parse results
258
+ xcresult_path = cache.get_path(xcresult_id) if xcresult_id else None
259
+ parser = XCResultParser(xcresult_path, stderr=stderr)
260
+ error_count, warning_count = parser.count_issues()
261
+
262
+ # Format output
263
+ status = "SUCCESS" if success else "FAILED"
264
+
265
+ # Collect errors on failure (used by all output modes)
266
+ errors = parser.get_errors() if not success else None
267
+ hints = OutputFormatter.generate_hints(errors) if errors else None
268
+
269
+ # Collect test info and failed tests when testing
270
+ test_info = None
271
+ failed_tests = None
272
+ if args.test and xcresult_path:
273
+ test_results = parser.get_test_results()
274
+ if test_results:
275
+ # Xcode 16 `xcresulttool get test-results summary` keys are
276
+ # totalTestCount / passedTests / failedTests (fall back to the
277
+ # legacy total/passed/failed names for older Xcode).
278
+ start = test_results.get("startTime")
279
+ finish = test_results.get("finishTime")
280
+ duration = (
281
+ round(finish - start, 1)
282
+ if isinstance(start, (int, float)) and isinstance(finish, (int, float))
283
+ else test_results.get("duration", 0.0)
284
+ )
285
+ test_info = {
286
+ "total": test_results.get("totalTestCount", test_results.get("total", 0)),
287
+ "passed": test_results.get("passedTests", test_results.get("passed", 0)),
288
+ "failed": test_results.get("failedTests", test_results.get("failed", 0)),
289
+ "duration": duration,
290
+ }
291
+ if not success:
292
+ failed_tests = parser.get_failed_tests()
293
+
294
+ if args.verbose:
295
+ # Verbose mode with error/warning details
296
+ verbose_errors = errors if error_count > 0 else None
297
+ warnings = parser.get_warnings() if warning_count > 0 else None
298
+
299
+ output = OutputFormatter.format_verbose(
300
+ status=status,
301
+ error_count=error_count,
302
+ warning_count=warning_count,
303
+ xcresult_id=xcresult_id or "N/A",
304
+ errors=verbose_errors,
305
+ warnings=warnings,
306
+ test_info=test_info,
307
+ )
308
+ print(output)
309
+ elif args.json:
310
+ # JSON mode
311
+ data = {
312
+ "success": success,
313
+ "xcresult_id": xcresult_id or None,
314
+ "error_count": error_count,
315
+ "warning_count": warning_count,
316
+ }
317
+ if test_info:
318
+ data["test_info"] = test_info
319
+ if not success:
320
+ if errors:
321
+ data["errors"] = errors[:BUILD_JSON_CAP]
322
+ if failed_tests:
323
+ data["failed_tests"] = failed_tests[:BUILD_JSON_CAP]
324
+ if hints:
325
+ data["hints"] = hints
326
+ import json
327
+
328
+ print(json.dumps(data, indent=2))
329
+ else:
330
+ # Minimal mode (default)
331
+ output = OutputFormatter.format_minimal(
332
+ status=status,
333
+ error_count=error_count,
334
+ warning_count=warning_count,
335
+ xcresult_id=xcresult_id or "N/A",
336
+ test_info=test_info,
337
+ hints=hints,
338
+ errors=errors,
339
+ failed_tests=failed_tests,
340
+ )
341
+ print(output)
342
+
343
+ # Exit with appropriate code
344
+ return 0 if success else 1
345
+
346
+
347
+ if __name__ == "__main__":
348
+ sys.exit(main())
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ iOS Simulator Clipboard Manager
4
+
5
+ Copy text to simulator clipboard for testing paste flows.
6
+ Optimized for minimal token output.
7
+
8
+ Usage: python scripts/clipboard.py --copy "text to copy"
9
+ """
10
+
11
+ import argparse
12
+ import subprocess
13
+ import sys
14
+
15
+ from common import resolve_udid
16
+
17
+
18
+ class ClipboardManager:
19
+ """Manages clipboard operations on iOS simulator."""
20
+
21
+ def __init__(self, udid: str | None = None):
22
+ """Initialize clipboard manager.
23
+
24
+ Args:
25
+ udid: Optional device UDID (auto-detects booted simulator if None)
26
+ """
27
+ self.udid = udid
28
+
29
+ def copy(self, text: str) -> bool:
30
+ """
31
+ Copy text to simulator clipboard.
32
+
33
+ Args:
34
+ text: Text to copy to clipboard
35
+
36
+ Returns:
37
+ Success status
38
+ """
39
+ cmd = ["xcrun", "simctl", "pbcopy"]
40
+
41
+ if self.udid:
42
+ cmd.append(self.udid)
43
+ else:
44
+ cmd.append("booted")
45
+
46
+ cmd.append(text)
47
+
48
+ try:
49
+ subprocess.run(cmd, capture_output=True, check=True)
50
+ return True
51
+ except subprocess.CalledProcessError:
52
+ return False
53
+
54
+
55
+ def main():
56
+ """Main entry point."""
57
+ parser = argparse.ArgumentParser(description="Copy text to iOS simulator clipboard")
58
+ parser.add_argument("--copy", required=True, help="Text to copy to clipboard")
59
+ parser.add_argument(
60
+ "--udid",
61
+ help="Device UDID (auto-detects booted simulator if not provided)",
62
+ )
63
+ parser.add_argument("--test-name", help="Test scenario name for tracking")
64
+ parser.add_argument("--expected", help="Expected behavior after paste")
65
+
66
+ args = parser.parse_args()
67
+
68
+ # Resolve UDID with auto-detection
69
+ try:
70
+ udid = resolve_udid(args.udid)
71
+ except RuntimeError as e:
72
+ print(f"Error: {e}")
73
+ sys.exit(1)
74
+
75
+ # Create manager and copy text
76
+ manager = ClipboardManager(udid=udid)
77
+
78
+ if manager.copy(args.copy):
79
+ # Token-efficient output
80
+ output = f'Copied: "{args.copy}"'
81
+
82
+ if args.test_name:
83
+ output += f" (test: {args.test_name})"
84
+
85
+ print(output)
86
+
87
+ # Provide usage guidance
88
+ if args.expected:
89
+ print(f"Expected: {args.expected}")
90
+
91
+ print()
92
+ print("Next steps:")
93
+ print("1. Tap text field with: python scripts/navigator.py --find-type TextField --tap")
94
+ print("2. Paste with: python scripts/keyboard.py --key return")
95
+ print(" Or use Cmd+V gesture with: python scripts/keyboard.py --key cmd+v")
96
+
97
+ else:
98
+ print("Failed to copy text to clipboard")
99
+ sys.exit(1)
100
+
101
+
102
+ if __name__ == "__main__":
103
+ main()
@@ -0,0 +1,61 @@
1
+ """
2
+ Common utilities shared across iOS simulator scripts.
3
+
4
+ This module centralizes genuinely reused code patterns to eliminate duplication
5
+ while respecting Jackson's Law - no over-abstraction, only truly shared logic.
6
+
7
+ Organization:
8
+ - device_utils: Device detection, command building, coordinate transformation
9
+ - idb_utils: IDB-specific operations (accessibility tree, element manipulation)
10
+ - cache_utils: Progressive disclosure caching for large outputs
11
+ - screenshot_utils: Screenshot capture with file and inline modes
12
+ """
13
+
14
+ from .cache_utils import ProgressiveCache, get_cache
15
+ from .device_utils import (
16
+ build_idb_command,
17
+ build_simctl_command,
18
+ get_booted_device_udid,
19
+ get_booted_device_udids,
20
+ get_device_screen_size,
21
+ resolve_udid,
22
+ transform_screenshot_coords,
23
+ )
24
+ from .idb_utils import (
25
+ count_elements,
26
+ flatten_tree,
27
+ get_accessibility_tree,
28
+ get_screen_size,
29
+ )
30
+ from .screenshot_utils import (
31
+ capture_screenshot,
32
+ format_screenshot_result,
33
+ generate_screenshot_name,
34
+ get_size_preset,
35
+ resize_screenshot,
36
+ )
37
+
38
+ __all__ = [
39
+ # cache_utils
40
+ "ProgressiveCache",
41
+ # device_utils
42
+ "build_idb_command",
43
+ "build_simctl_command",
44
+ # screenshot_utils
45
+ "capture_screenshot",
46
+ # idb_utils
47
+ "count_elements",
48
+ "flatten_tree",
49
+ "format_screenshot_result",
50
+ "generate_screenshot_name",
51
+ "get_accessibility_tree",
52
+ "get_booted_device_udid",
53
+ "get_booted_device_udids",
54
+ "get_cache",
55
+ "get_device_screen_size",
56
+ "get_screen_size",
57
+ "get_size_preset",
58
+ "resize_screenshot",
59
+ "resolve_udid",
60
+ "transform_screenshot_coords",
61
+ ]