@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.
- package/bin/awk.js +576 -84
- package/core/CLAUDE.md +1 -1
- package/core/GEMINI.md +148 -167
- package/core/GEMINI.md.bak +149 -116
- package/core/skill-runtime-manifest.json +3 -0
- package/docs/Claude Fable 5.md +3826 -0
- package/docs/android_kotlin_system_instruction.md +210 -0
- package/docs/brainstorm_ponytail_integration.md +146 -0
- package/docs/brainstorm_smart_setup.md +113 -0
- package/docs/deep-research-report (1).md +293 -0
- package/docs/history/GEMINI.v1.md +135 -0
- package/docs/history/brainstorm_antigravity_unified_architecture.v1.md +105 -0
- package/docs/history/implementation_plan.v1.md +58 -0
- package/package.json +4 -1
- package/scripts/artifact-storage.js +130 -0
- package/scripts/automation-gate.js +35 -2
- package/scripts/claude-plan.js +76 -0
- package/scripts/dependency-manager.js +210 -0
- package/scripts/exec-rtk.js +11 -5
- package/scripts/i18n-helper.js +381 -0
- package/scripts/multi-model-pipeline.js +144 -0
- package/skill-packs/mobile-ios/pack.json +4 -2
- package/skill-packs/reverse-engineering/pack.json +1 -0
- package/skills/CATALOG.md +20 -0
- package/skills/GEMINI.md +9 -1
- package/skills/TRIGGER_INDEX.md +10 -0
- package/skills/ai-music/SKILL.md +275 -0
- package/skills/android-re-analyzer/SKILL.md +238 -0
- package/skills/android-re-analyzer/references/api-extraction-patterns.md +119 -0
- package/skills/android-re-analyzer/references/call-flow-analysis.md +176 -0
- package/skills/android-re-analyzer/references/fernflower-usage.md +115 -0
- package/skills/android-re-analyzer/references/jadx-usage.md +116 -0
- package/skills/android-re-analyzer/references/setup-guide.md +221 -0
- package/skills/android-re-analyzer/scripts/check-deps.sh +129 -0
- package/skills/android-re-analyzer/scripts/decompile.sh +375 -0
- package/skills/android-re-analyzer/scripts/find-api-calls.sh +118 -0
- package/skills/android-re-analyzer/scripts/install-dep.sh +448 -0
- package/skills/animal-island-ui-style/SKILL.md +1450 -0
- package/skills/app-store-review-agent/SKILL.md +164 -0
- package/skills/app-store-review-agent/references/guidelines/README.md +154 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/ai_apps.md +37 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/all_apps.md +50 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/crypto_finance.md +31 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/games.md +31 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/health_fitness.md +31 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/kids.md +27 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/macos.md +38 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/social_ugc.md +32 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/subscription_iap.md +34 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/vpn.md +18 -0
- package/skills/app-store-review-agent/references/rules/design/minimum_functionality.md +96 -0
- package/skills/app-store-review-agent/references/rules/design/sign_in_with_apple.md +54 -0
- package/skills/app-store-review-agent/references/rules/entitlements/unused_entitlements.md +83 -0
- package/skills/app-store-review-agent/references/rules/metadata/accurate_metadata.md +54 -0
- package/skills/app-store-review-agent/references/rules/metadata/apple_trademark.md +99 -0
- package/skills/app-store-review-agent/references/rules/metadata/china_storefront.md +72 -0
- package/skills/app-store-review-agent/references/rules/metadata/competitor_terms.md +56 -0
- package/skills/app-store-review-agent/references/rules/metadata/subscription_metadata.md +81 -0
- package/skills/app-store-review-agent/references/rules/privacy/privacy_manifest.md +84 -0
- package/skills/app-store-review-agent/references/rules/privacy/unnecessary_data.md +60 -0
- package/skills/app-store-review-agent/references/rules/subscription/misleading_pricing.md +63 -0
- package/skills/app-store-review-agent/references/rules/subscription/missing_tos_pp.md +54 -0
- package/skills/awf-ponytail/SKILL.md +91 -0
- package/skills/awf-ponytail-review/SKILL.md +67 -0
- package/skills/awf-session-restore/SKILL.md +3 -3
- package/skills/brainstorm-agent/SKILL.md +11 -2
- package/skills/brainstorm-agent/templates/brief-template.md +8 -0
- package/skills/claude-planner/SKILL.md +47 -0
- package/skills/code-review/SKILL.md +87 -0
- package/skills/expo-game-development/SKILL.md +163 -0
- package/skills/flutter/LICENSE.txt +202 -0
- package/skills/flutter/SKILL.md +127 -0
- package/skills/flutter-project-creater/LICENSE.txt +202 -0
- package/skills/flutter-project-creater/SKILL.md +106 -0
- package/skills/game-developer/SKILL.md +163 -0
- package/skills/game-developer/references/ecs-patterns.md +501 -0
- package/skills/game-developer/references/multiplayer-networking.md +475 -0
- package/skills/game-developer/references/performance-optimization.md +422 -0
- package/skills/game-developer/references/unity-patterns.md +271 -0
- package/skills/game-developer/references/unreal-cpp.md +352 -0
- package/skills/generate-gui-assets/SKILL.md +305 -0
- package/skills/generate-gui-assets/agents/openai.yaml +4 -0
- package/skills/generate-gui-assets/references/catalog-schema.md +58 -0
- package/skills/generate-gui-assets/references/extraction-techniques.md +21 -0
- package/skills/generate-gui-assets/references/prompt-patterns.md +58 -0
- package/skills/generate-gui-assets/scripts/__pycache__/clean_chroma_edges.cpython-311.pyc +0 -0
- package/skills/generate-gui-assets/scripts/build_gui_contact_sheet.py +51 -0
- package/skills/generate-gui-assets/scripts/clean_chroma_edges.py +262 -0
- package/skills/generate-gui-assets/scripts/copy_approved_icons.py +64 -0
- package/skills/generate-gui-assets/scripts/prepare_gui_asset_run.py +91 -0
- package/skills/generate-gui-assets/scripts/suggest_grid_options.py +63 -0
- package/skills/generate-gui-assets/scripts/validate_gui_catalog.py +50 -0
- package/skills/godot-game-development/SKILL.md +142 -0
- package/skills/hatch-pet/LICENSE.txt +201 -0
- package/skills/hatch-pet/SKILL.md +420 -0
- package/skills/hatch-pet/agents/openai.yaml +4 -0
- package/skills/hatch-pet/references/animation-rows.md +29 -0
- package/skills/hatch-pet/references/codex-pet-contract.md +35 -0
- package/skills/hatch-pet/references/qa-rubric.md +60 -0
- package/skills/hatch-pet/scripts/__pycache__/clean_chroma_edges.cpython-311.pyc +0 -0
- package/skills/hatch-pet/scripts/clean_chroma_edges.py +262 -0
- package/skills/hatch-pet/scripts/compose_atlas.py +150 -0
- package/skills/hatch-pet/scripts/derive_running_left_from_running_right.py +143 -0
- package/skills/hatch-pet/scripts/extract_strip_frames.py +323 -0
- package/skills/hatch-pet/scripts/finalize_pet_run.py +382 -0
- package/skills/hatch-pet/scripts/generate_pet_images.py +287 -0
- package/skills/hatch-pet/scripts/inspect_frames.py +246 -0
- package/skills/hatch-pet/scripts/make_contact_sheet.py +96 -0
- package/skills/hatch-pet/scripts/package_custom_pet.py +108 -0
- package/skills/hatch-pet/scripts/pet_job_status.py +117 -0
- package/skills/hatch-pet/scripts/prepare_pet_run.py +673 -0
- package/skills/hatch-pet/scripts/queue_pet_repairs.py +172 -0
- package/skills/hatch-pet/scripts/record_imagegen_result.py +250 -0
- package/skills/hatch-pet/scripts/render_animation_videos.py +134 -0
- package/skills/hatch-pet/scripts/render_animation_videos.sh +5 -0
- package/skills/hatch-pet/scripts/validate_atlas.py +139 -0
- package/skills/i18n-orchestrator/SKILL.md +37 -0
- package/skills/ios-simulator-skill/SKILL.md +390 -0
- package/skills/ios-simulator-skill/scripts/accessibility_audit.py +300 -0
- package/skills/ios-simulator-skill/scripts/app_launcher.py +326 -0
- package/skills/ios-simulator-skill/scripts/app_state_capture.py +400 -0
- package/skills/ios-simulator-skill/scripts/appearance.py +385 -0
- package/skills/ios-simulator-skill/scripts/build_and_test.py +348 -0
- package/skills/ios-simulator-skill/scripts/clipboard.py +103 -0
- package/skills/ios-simulator-skill/scripts/common/__init__.py +61 -0
- package/skills/ios-simulator-skill/scripts/common/cache_utils.py +289 -0
- package/skills/ios-simulator-skill/scripts/common/device_utils.py +462 -0
- package/skills/ios-simulator-skill/scripts/common/env_config.py +35 -0
- package/skills/ios-simulator-skill/scripts/common/hang_pipeline.py +862 -0
- package/skills/ios-simulator-skill/scripts/common/hang_sessions.py +490 -0
- package/skills/ios-simulator-skill/scripts/common/idb_utils.py +180 -0
- package/skills/ios-simulator-skill/scripts/common/screenshot_utils.py +338 -0
- package/skills/ios-simulator-skill/scripts/container.py +668 -0
- package/skills/ios-simulator-skill/scripts/gesture.py +394 -0
- package/skills/ios-simulator-skill/scripts/hang_watcher.py +1533 -0
- package/skills/ios-simulator-skill/scripts/keyboard.py +391 -0
- package/skills/ios-simulator-skill/scripts/localization_audit.py +483 -0
- package/skills/ios-simulator-skill/scripts/location.py +467 -0
- package/skills/ios-simulator-skill/scripts/log_monitor.py +493 -0
- package/skills/ios-simulator-skill/scripts/model_inspector.py +645 -0
- package/skills/ios-simulator-skill/scripts/navigator.py +461 -0
- package/skills/ios-simulator-skill/scripts/privacy_manager.py +310 -0
- package/skills/ios-simulator-skill/scripts/push_notification.py +240 -0
- package/skills/ios-simulator-skill/scripts/screen_mapper.py +296 -0
- package/skills/ios-simulator-skill/scripts/sim_health_check.sh +245 -0
- package/skills/ios-simulator-skill/scripts/sim_list.py +299 -0
- package/skills/ios-simulator-skill/scripts/simctl_boot.py +312 -0
- package/skills/ios-simulator-skill/scripts/simctl_create.py +316 -0
- package/skills/ios-simulator-skill/scripts/simctl_delete.py +357 -0
- package/skills/ios-simulator-skill/scripts/simctl_erase.py +351 -0
- package/skills/ios-simulator-skill/scripts/simctl_shutdown.py +290 -0
- package/skills/ios-simulator-skill/scripts/simulator_selector.py +375 -0
- package/skills/ios-simulator-skill/scripts/status_bar.py +250 -0
- package/skills/ios-simulator-skill/scripts/test_recorder.py +323 -0
- package/skills/ios-simulator-skill/scripts/visual_diff.py +235 -0
- package/skills/ios-simulator-skill/scripts/xcode/__init__.py +13 -0
- package/skills/ios-simulator-skill/scripts/xcode/builder.py +397 -0
- package/skills/ios-simulator-skill/scripts/xcode/cache.py +204 -0
- package/skills/ios-simulator-skill/scripts/xcode/config.py +178 -0
- package/skills/ios-simulator-skill/scripts/xcode/reporter.py +343 -0
- package/skills/ios-simulator-skill/scripts/xcode/xcresult.py +451 -0
- package/skills/ios-visual-qa-strategist/SKILL.md +111 -0
- package/skills/ios-visual-qa-strategist/agents/openai.yaml +4 -0
- package/skills/ios-visual-qa-strategist/references/ios-tool-selection.md +61 -0
- package/skills/ios-visual-qa-strategist/references/minimal-capture-policy.md +56 -0
- package/skills/ios-visual-qa-strategist/references/visual-reasoning-heuristics.md +53 -0
- package/skills/orchestrator/SKILL.md +0 -20
- package/skills/persistent-storage/SKILL.md +55 -0
- package/skills/short-maker/SKILL.md +23 -0
- package/skills/short-maker/scripts/effects.js +56 -0
- package/skills/short-maker/scripts/shortmaker-bridge.js +332 -0
- package/skills/short-maker/scripts/videomix.js +601 -0
- package/skills/short-maker/templates/hyperframes/cinematic-character.template.html +172 -0
- package/skills/short-maker/templates/hyperframes/index.template.html +194 -0
- package/skills/smali-to-kotlin/SKILL.md +128 -0
- package/skills/smali-to-kotlin/examples/getting-started/tech-stack.md +58 -0
- package/skills/smali-to-kotlin/examples/pipeline/data-ui-parity.md +118 -0
- package/skills/smali-to-kotlin/examples/pipeline/scanner-and-bootstrap.md +106 -0
- package/skills/smali-to-kotlin/library-patterns.md +189 -0
- package/skills/smali-to-kotlin/phase-0-discovery.md +128 -0
- package/skills/smali-to-kotlin/phase-1-architecture.md +166 -0
- package/skills/smali-to-kotlin/phase-2-blueprint-ui.md +347 -0
- package/skills/smali-to-kotlin/phase-2-blueprint.md +228 -0
- package/skills/smali-to-kotlin/phase-3-build.md +248 -0
- package/skills/smali-to-kotlin/phase-3-logic-build.md +268 -0
- package/skills/smali-to-kotlin/smali-reading-guide.md +310 -0
- package/skills/smali-to-kotlin/templates/app-map.md +101 -0
- package/skills/smali-to-kotlin/templates/architecture.md +142 -0
- package/skills/smali-to-kotlin/templates/blueprint.md +145 -0
- package/skills/spec-gate/SKILL.md +6 -2
- package/skills/symphony-enforcer/SKILL.md +8 -0
- package/skills/symphony-enforcer/examples/mindful-stop.md +2 -0
- package/skills/symphony-enforcer/examples/three-phase.md +16 -0
- package/skills/symphony-enforcer/examples/trigger-points.md +7 -1
- package/skills/unity-game-development/SKILL.md +231 -0
- package/skills/video-edit/SKILL.md +36 -0
- package/skills/video-edit/scripts/video_edit.py +324 -0
- package/templates/project-identity/android.json +2 -2
- package/templates/project-identity/backend-nestjs.json +2 -2
- package/templates/project-identity/expo.json +2 -2
- package/templates/project-identity/ios.json +2 -2
- package/templates/project-identity/web-nextjs.json +2 -2
- package/templates/setup-mapping.json +48 -0
- package/templates/specs/design-template.md +161 -71
- package/templates/specs/requirements-template.md +65 -133
- package/templates/specs/task-spec-template.xml +3 -0
- package/workflows/_uncategorized/critic.md +40 -0
- package/workflows/_uncategorized/git-rebase-flow.md +81 -0
- package/workflows/_uncategorized/image-gen.md +118 -0
- package/workflows/_uncategorized/multi-model-pipeline.md +60 -0
- package/workflows/_uncategorized/pixel-gen.md +86 -0
- package/workflows/_uncategorized/pixel-setup.md +90 -0
- package/workflows/_uncategorized/ponytail-review.md +59 -0
- package/workflows/_uncategorized/reverse-android-build.md +222 -0
- package/workflows/_uncategorized/reverse-android-design.md +139 -0
- package/workflows/_uncategorized/reverse-android-discover.md +150 -0
- package/workflows/_uncategorized/reverse-android-scan.md +158 -0
- package/workflows/_uncategorized/reverse-android.md +143 -0
- package/workflows/_uncategorized/reverse-ios-build.md +240 -0
- package/workflows/_uncategorized/reverse-ios-design.md +112 -0
- package/workflows/_uncategorized/reverse-ios-discover.md +120 -0
- package/workflows/_uncategorized/reverse-ios-scan.md +155 -0
- package/workflows/_uncategorized/reverse-ios.md +152 -0
- package/workflows/_uncategorized/safety-router.md +34 -0
- package/workflows/_uncategorized/teach.md +89 -0
- package/workflows/_uncategorized/verify-ui.md +53 -0
- package/workflows/_uncategorized/visualize-screenshots.md +34 -0
- package/workflows/ads/ads-analyst.md +201 -0
- package/workflows/ads/ads-audit.md +106 -0
- package/workflows/ads/ads-optimize.md +97 -0
- package/workflows/ads/ads-targeting.md +241 -0
- package/workflows/ads/adsExpert.md +160 -0
- package/workflows/ads/smali-ads-config.md +400 -0
- package/workflows/ads/smali-ads-flow.md +331 -0
- package/workflows/ads/smali-ads-interstitial.md +377 -0
- package/workflows/ads/smali-ads-native.md +382 -0
- package/workflows/context/teach.md +89 -0
- package/workflows/gitnexus.md +8 -8
- package/workflows/lifecycle/brainstorm.md +43 -0
- package/workflows/lifecycle/code.md +5 -0
- package/workflows/lifecycle/init.md +23 -5
- package/workflows/lifecycle/multi-model-pipeline.md +60 -0
- package/workflows/quality/ponytail-review.md +59 -0
- package/workflows/roles/critic.md +40 -0
- 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
|
+
]
|