@leejungkiin/awkit 1.4.0 → 1.4.2

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 (119) hide show
  1. package/bin/awk.js +432 -6
  2. package/bin/claude-generators.js +122 -0
  3. package/core/AGENTS.md +16 -0
  4. package/core/CLAUDE.md +155 -0
  5. package/core/GEMINI.md +44 -9
  6. package/package.json +1 -1
  7. package/skills/ai-sprite-maker/SKILL.md +81 -0
  8. package/skills/ai-sprite-maker/scripts/animate_sprite.py +102 -0
  9. package/skills/ai-sprite-maker/scripts/process_sprites.py +140 -0
  10. package/skills/code-review/SKILL.md +21 -33
  11. package/skills/lucylab-tts/SKILL.md +64 -0
  12. package/skills/lucylab-tts/resources/voices_library.json +908 -0
  13. package/skills/lucylab-tts/scripts/.env +1 -0
  14. package/skills/lucylab-tts/scripts/lucylab_tts.py +506 -0
  15. package/skills/orchestrator/SKILL.md +5 -0
  16. package/skills/short-maker/SKILL.md +150 -0
  17. package/skills/short-maker/_backup/storyboard.html +106 -0
  18. package/skills/short-maker/_backup/video_mixer.py +296 -0
  19. package/skills/short-maker/outputs/fitbite-promo/background.jpg +0 -0
  20. package/skills/short-maker/outputs/fitbite-promo/final/promo-final.mp4 +0 -0
  21. package/skills/short-maker/outputs/fitbite-promo/script.md +19 -0
  22. package/skills/short-maker/outputs/fitbite-promo/segments/scene-01.mp4 +0 -0
  23. package/skills/short-maker/outputs/fitbite-promo/segments/scene-02.mp4 +0 -0
  24. package/skills/short-maker/outputs/fitbite-promo/segments/scene-03.mp4 +0 -0
  25. package/skills/short-maker/outputs/fitbite-promo/segments/scene-04.mp4 +0 -0
  26. package/skills/short-maker/outputs/fitbite-promo/storyboard/scene-01.png +0 -0
  27. package/skills/short-maker/outputs/fitbite-promo/storyboard/scene-02.png +0 -0
  28. package/skills/short-maker/outputs/fitbite-promo/storyboard/scene-03.png +0 -0
  29. package/skills/short-maker/outputs/fitbite-promo/storyboard/scene-04.png +0 -0
  30. package/skills/short-maker/outputs/fitbite-promo/storyboard.html +133 -0
  31. package/skills/short-maker/outputs/fitbite-promo/storyboard.json +38 -0
  32. package/skills/short-maker/outputs/fitbite-promo/temp/merged_chroma.mp4 +0 -0
  33. package/skills/short-maker/outputs/fitbite-promo/temp/merged_crossfaded.mp4 +0 -0
  34. package/skills/short-maker/outputs/fitbite-promo/temp/ready_00.mp4 +0 -0
  35. package/skills/short-maker/outputs/fitbite-promo/temp/ready_01.mp4 +0 -0
  36. package/skills/short-maker/outputs/fitbite-promo/temp/ready_02.mp4 +0 -0
  37. package/skills/short-maker/outputs/fitbite-promo/temp/ready_03.mp4 +0 -0
  38. package/skills/short-maker/outputs/fitbite-promo/tts/manifest.json +31 -0
  39. package/skills/short-maker/outputs/fitbite-promo/tts/scene-01.wav +0 -0
  40. package/skills/short-maker/outputs/fitbite-promo/tts/scene-02.wav +0 -0
  41. package/skills/short-maker/outputs/fitbite-promo/tts/scene-03.wav +0 -0
  42. package/skills/short-maker/outputs/fitbite-promo/tts/scene-04.wav +0 -0
  43. package/skills/short-maker/outputs/fitbite-promo/tts_script.txt +11 -0
  44. package/skills/short-maker/scripts/google-flow-cli/.project-identity +41 -0
  45. package/skills/short-maker/scripts/google-flow-cli/.trae/rules/project_rules.md +52 -0
  46. package/skills/short-maker/scripts/google-flow-cli/CODEBASE.md +67 -0
  47. package/skills/short-maker/scripts/google-flow-cli/GoogleFlowCli.code-workspace +29 -0
  48. package/skills/short-maker/scripts/google-flow-cli/README.md +168 -0
  49. package/skills/short-maker/scripts/google-flow-cli/docs/specs/PROJECT.md +12 -0
  50. package/skills/short-maker/scripts/google-flow-cli/docs/specs/REQUIREMENTS.md +22 -0
  51. package/skills/short-maker/scripts/google-flow-cli/docs/specs/ROADMAP.md +16 -0
  52. package/skills/short-maker/scripts/google-flow-cli/docs/specs/TECH-SPEC.md +13 -0
  53. package/skills/short-maker/scripts/google-flow-cli/gflow/__init__.py +3 -0
  54. package/skills/short-maker/scripts/google-flow-cli/gflow/api/__init__.py +19 -0
  55. package/skills/short-maker/scripts/google-flow-cli/gflow/api/client.py +1921 -0
  56. package/skills/short-maker/scripts/google-flow-cli/gflow/api/models.py +64 -0
  57. package/skills/short-maker/scripts/google-flow-cli/gflow/api/rpc_ids.py +98 -0
  58. package/skills/short-maker/scripts/google-flow-cli/gflow/auth/__init__.py +15 -0
  59. package/skills/short-maker/scripts/google-flow-cli/gflow/auth/browser_auth.py +692 -0
  60. package/skills/short-maker/scripts/google-flow-cli/gflow/auth/humanizer.py +417 -0
  61. package/skills/short-maker/scripts/google-flow-cli/gflow/auth/proxy_ext.py +120 -0
  62. package/skills/short-maker/scripts/google-flow-cli/gflow/auth/recaptcha.py +482 -0
  63. package/skills/short-maker/scripts/google-flow-cli/gflow/batchexecute/__init__.py +5 -0
  64. package/skills/short-maker/scripts/google-flow-cli/gflow/batchexecute/client.py +414 -0
  65. package/skills/short-maker/scripts/google-flow-cli/gflow/cli/__init__.py +1 -0
  66. package/skills/short-maker/scripts/google-flow-cli/gflow/cli/main.py +1075 -0
  67. package/skills/short-maker/scripts/google-flow-cli/pyproject.toml +36 -0
  68. package/skills/short-maker/scripts/google-flow-cli/script.txt +22 -0
  69. package/skills/short-maker/scripts/google-flow-cli/tests/__init__.py +0 -0
  70. package/skills/short-maker/scripts/google-flow-cli/tests/test_batchexecute.py +113 -0
  71. package/skills/short-maker/scripts/google-flow-cli/tests/test_client.py +190 -0
  72. package/skills/short-maker/templates/aida_script.md +40 -0
  73. package/skills/short-maker/templates/mimic_analyzer.md +29 -0
  74. package/skills/single-flow-task-execution/SKILL.md +9 -6
  75. package/skills/skill-creator/SKILL.md +44 -0
  76. package/skills/spm-build-analysis/SKILL.md +92 -0
  77. package/skills/spm-build-analysis/references/build-optimization-sources.md +155 -0
  78. package/skills/spm-build-analysis/references/recommendation-format.md +85 -0
  79. package/skills/spm-build-analysis/references/spm-analysis-checks.md +105 -0
  80. package/skills/spm-build-analysis/scripts/check_spm_pins.py +118 -0
  81. package/skills/symphony-enforcer/SKILL.md +51 -83
  82. package/skills/symphony-orchestrator/SKILL.md +1 -1
  83. package/skills/trello-sync/SKILL.md +27 -28
  84. package/skills/verification-gate/SKILL.md +13 -2
  85. package/skills/xcode-build-benchmark/SKILL.md +88 -0
  86. package/skills/xcode-build-benchmark/references/benchmark-artifacts.md +94 -0
  87. package/skills/xcode-build-benchmark/references/benchmarking-workflow.md +67 -0
  88. package/skills/xcode-build-benchmark/schemas/build-benchmark.schema.json +230 -0
  89. package/skills/xcode-build-benchmark/scripts/benchmark_builds.py +308 -0
  90. package/skills/xcode-build-fixer/SKILL.md +218 -0
  91. package/skills/xcode-build-fixer/references/build-settings-best-practices.md +216 -0
  92. package/skills/xcode-build-fixer/references/fix-patterns.md +290 -0
  93. package/skills/xcode-build-fixer/references/recommendation-format.md +85 -0
  94. package/skills/xcode-build-fixer/scripts/benchmark_builds.py +308 -0
  95. package/skills/xcode-build-orchestrator/SKILL.md +156 -0
  96. package/skills/xcode-build-orchestrator/references/benchmark-artifacts.md +94 -0
  97. package/skills/xcode-build-orchestrator/references/build-settings-best-practices.md +216 -0
  98. package/skills/xcode-build-orchestrator/references/orchestration-report-template.md +143 -0
  99. package/skills/xcode-build-orchestrator/references/recommendation-format.md +85 -0
  100. package/skills/xcode-build-orchestrator/scripts/benchmark_builds.py +308 -0
  101. package/skills/xcode-build-orchestrator/scripts/diagnose_compilation.py +273 -0
  102. package/skills/xcode-build-orchestrator/scripts/generate_optimization_report.py +533 -0
  103. package/skills/xcode-compilation-analyzer/SKILL.md +89 -0
  104. package/skills/xcode-compilation-analyzer/references/build-optimization-sources.md +155 -0
  105. package/skills/xcode-compilation-analyzer/references/code-compilation-checks.md +106 -0
  106. package/skills/xcode-compilation-analyzer/references/recommendation-format.md +85 -0
  107. package/skills/xcode-compilation-analyzer/scripts/diagnose_compilation.py +273 -0
  108. package/skills/xcode-project-analyzer/SKILL.md +76 -0
  109. package/skills/xcode-project-analyzer/references/build-optimization-sources.md +155 -0
  110. package/skills/xcode-project-analyzer/references/build-settings-best-practices.md +216 -0
  111. package/skills/xcode-project-analyzer/references/project-audit-checks.md +101 -0
  112. package/skills/xcode-project-analyzer/references/recommendation-format.md +85 -0
  113. package/templates/project-identity/android.json +0 -10
  114. package/templates/project-identity/backend-nestjs.json +0 -10
  115. package/templates/project-identity/expo.json +0 -10
  116. package/templates/project-identity/ios.json +0 -10
  117. package/templates/project-identity/web-nextjs.json +0 -10
  118. package/workflows/_uncategorized/ship-to-code.md +85 -0
  119. package/workflows/context/codebase-sync.md +10 -87
@@ -0,0 +1,155 @@
1
+ # Build Optimization Sources
2
+
3
+ This file stores the external sources that the README and skill docs should cite consistently.
4
+
5
+ ## Apple: Improving the speed of incremental builds
6
+
7
+ Source:
8
+
9
+ - <https://developer.apple.com/documentation/xcode/improving-the-speed-of-incremental-builds>
10
+
11
+ Key takeaways:
12
+
13
+ - Measure first with `Build With Timing Summary` or `xcodebuild -showBuildTimingSummary`.
14
+ - Accurate target dependencies improve correctness and parallelism.
15
+ - Run scripts should declare inputs and outputs so Xcode can skip unnecessary work.
16
+ - `.xcfilelist` files are appropriate when scripts have many inputs or outputs.
17
+ - Custom frameworks and libraries benefit from module maps, typically by enabling `DEFINES_MODULE`.
18
+ - Module reuse is strongest when related sources compile with consistent options.
19
+ - Breaking monolithic targets into better-scoped modules can reduce unnecessary rebuilds.
20
+
21
+ ## Apple: Improving build efficiency with good coding practices
22
+
23
+ Source:
24
+
25
+ - <https://developer.apple.com/documentation/xcode/improving-build-efficiency-with-good-coding-practices>
26
+
27
+ Key takeaways:
28
+
29
+ - Use framework-qualified imports when module maps are available.
30
+ - Keep Objective-C bridging surfaces narrow.
31
+ - Prefer explicit type information when inference becomes expensive.
32
+ - Use explicit delegate protocols instead of overly generic delegate types.
33
+ - Simplify complex expressions that are hard for the compiler to type-check.
34
+
35
+ ## Apple: Building your project with explicit module dependencies
36
+
37
+ Source:
38
+
39
+ - <https://developer.apple.com/documentation/xcode/building-your-project-with-explicit-module-dependencies>
40
+
41
+ Key takeaways:
42
+
43
+ - Explicit module builds make module work visible in the build log and improve scheduling.
44
+ - Repeated builds of the same module often point to avoidable module variants.
45
+ - Inconsistent build options across targets can force duplicate module builds.
46
+ - Timing summaries can reveal option drift that prevents module reuse.
47
+
48
+ ## SwiftLee: Build performance analysis for speeding up Xcode builds
49
+
50
+ Source:
51
+
52
+ - <https://www.avanderlee.com/optimization/analysing-build-performance-xcode/>
53
+
54
+ Key takeaways:
55
+
56
+ - Clean and incremental builds should both be measured because they reveal different problems.
57
+ - Build Timeline and Build Timing Summary are practical starting points for build optimization.
58
+ - Build scripts often produce large incremental-build wins when guarded correctly.
59
+ - `-warn-long-function-bodies` and `-warn-long-expression-type-checking` help surface compile hotspots.
60
+ - Typical debug and release build setting mismatches are worth auditing, especially in older projects.
61
+
62
+ ## Apple: Xcode Release Notes -- Compilation Caching
63
+
64
+ Source:
65
+
66
+ - Xcode Release Notes (149700201)
67
+
68
+ Key takeaways:
69
+
70
+ - Compilation caching is an opt-in feature for Swift and C-family languages.
71
+ - It caches prior compilation results and reuses them when the same source inputs are recompiled.
72
+ - Branch switching and clean builds benefit the most.
73
+ - Can be enabled via the "Enable Compilation Caching" build setting or per-user project settings.
74
+
75
+ ## Apple: Demystify explicitly built modules (WWDC24)
76
+
77
+ Source:
78
+
79
+ - <https://developer.apple.com/videos/play/wwdc2024/10171/>
80
+
81
+ Key takeaways:
82
+
83
+ - Explains how explicitly built modules divide compilation into scan, module build, and source compile stages.
84
+ - Unrelated modules build in parallel, improving CPU utilization.
85
+ - Module variant duplication is a key bottleneck -- uniform compiler options across targets prevent it.
86
+ - The build log shows each module as a discrete task, making it easier to diagnose scheduling issues.
87
+
88
+ ## Swift Compile-Time Best Practices
89
+
90
+ Well-known Swift language patterns that reduce type-checker workload during compilation:
91
+
92
+ - Mark classes `final` when they are not intended for subclassing. This eliminates dynamic dispatch overhead and allows the compiler to de-virtualize method calls.
93
+ - Restrict access control to the narrowest useful scope (`private`, `fileprivate`). Fewer visible symbols reduce the compiler's search space during type resolution.
94
+ - Prefer value types (`struct`, `enum`) over `class` when reference semantics are not needed. Value types are simpler for the compiler to reason about.
95
+ - Break long method chains (`.map().flatMap().filter()`) into intermediate `let` bindings with explicit type annotations. Even simple-looking chains can take seconds to type-check.
96
+ - Provide explicit return types on closures passed to generic functions, especially in SwiftUI result-builder contexts.
97
+ - Decompose large SwiftUI `body` properties into smaller extracted subviews. Each subview narrows the scope of the result-builder expression the type-checker must resolve.
98
+
99
+ ## Bitrise: Demystifying Explicitly Built Modules for Xcode
100
+
101
+ Source:
102
+
103
+ - <https://bitrise.io/blog/post/demystifying-explicitly-built-modules-for-xcode>
104
+
105
+ Key takeaways:
106
+
107
+ - Explicit module builds give `xcodebuild` visibility into smaller compilation tasks for better parallelism.
108
+ - Enabled by default for C/Objective-C in Xcode 16+; experimental for Swift.
109
+ - Minimizing module variants by aligning build options is the primary optimization lever.
110
+ - Some projects see regressions from dependency scanning overhead -- benchmark before and after.
111
+
112
+ ## Bitrise: Xcode Compilation Cache FAQ
113
+
114
+ Source:
115
+
116
+ - <https://docs.bitrise.io/en/bitrise-build-cache/build-cache-for-xcode/xcode-compilation-cache-faq.html>
117
+
118
+ Key takeaways:
119
+
120
+ - Granular caching is controlled by `SWIFT_ENABLE_COMPILE_CACHE` and `CLANG_ENABLE_COMPILE_CACHE`, under the umbrella `COMPILATION_CACHING` setting.
121
+ - Non-cacheable tasks include `CompileStoryboard`, `CompileXIB`, `CompileAssetCatalogVariant`, `PhaseScriptExecution`, `DataModelCompile`, `CopyPNGFile`, `GenerateDSYMFile`, and `Ld`.
122
+ - SPM dependencies are not yet cacheable as of Xcode 26 beta.
123
+
124
+ ## RocketSim Docs: Build Insights
125
+
126
+ Sources:
127
+
128
+ - <https://www.rocketsim.app/docs/features/build-insights/build-insights/>
129
+ - <https://www.rocketsim.app/docs/features/build-insights/team-build-insights/>
130
+
131
+ Key takeaways:
132
+
133
+ - RocketSim automatically tracks clean vs incremental builds over time without build scripts.
134
+ - It reports build counts, duration trends, and percentile-based metrics such as p75 and p95.
135
+ - Team Build Insights adds machine, Xcode, and macOS comparisons for cross-team visibility.
136
+ - This repository is best positioned as the point-in-time analyze-and-improve toolkit, while RocketSim is the monitor-over-time companion.
137
+
138
+ ## Swift Forums: Slow incremental builds because of planning swift module
139
+
140
+ Source:
141
+
142
+ - <https://forums.swift.org/t/slow-incremental-builds-because-of-planning-swift-module/84803>
143
+
144
+ Key takeaways:
145
+
146
+ - "Planning Swift module" can dominate incremental builds (up to 30s per module), sometimes exceeding clean build time.
147
+ - Replanning every module without scheduling compiles is a sign that build inputs are being modified unexpectedly (e.g., a misconfigured linter touching file timestamps).
148
+ - Enable **Task Backtraces** (Xcode 16.4+: Scheme Editor > Build > Build Debugging) to see why each task re-ran in an incremental build.
149
+ - Heavy Swift macro usage (e.g., TCA / swift-syntax) can cause trivial changes to cascade into near-full rebuilds.
150
+ - `swift-syntax` builds universally (all architectures) when no prebuilt binary is available, adding significant overhead.
151
+ - `SwiftEmitModule` can take 60s+ after a single-line change in large modules.
152
+ - Asset catalog compilation is single-threaded per target; splitting assets into separate bundles across targets enables parallel compilation.
153
+ - Multi-platform targets (e.g., adding watchOS) can cause SPM packages to build 3x (iOS arm64, iOS x86_64, watchOS arm64).
154
+ - Zero-change incremental builds still incur ~10s of fixed overhead: compute dependencies, send project description, create build description, script phases, codesigning, and validation.
155
+ - Codesigning and validation run even when output has not changed.
@@ -0,0 +1,85 @@
1
+ # Recommendation Format
2
+
3
+ All optimization skills should report recommendations in a shared structure so the orchestrator can merge and prioritize them cleanly.
4
+
5
+ ## Required Fields
6
+
7
+ Each recommendation should include:
8
+
9
+ - `title`
10
+ - `wait_time_impact` -- plain-language statement of expected wall-clock impact, e.g. "Expected to reduce your clean build by ~3s", "Reduces parallel compile work but unlikely to reduce build wait time", or "Impact on wait time is uncertain -- re-benchmark to confirm"
11
+ - `actionability` -- classifies how fixable the issue is from the project (see values below)
12
+ - `category`
13
+ - `observed_evidence`
14
+ - `estimated_impact`
15
+ - `confidence`
16
+ - `approval_required`
17
+ - `benchmark_verification_status`
18
+
19
+ ### Actionability Values
20
+
21
+ Every recommendation must include an `actionability` classification:
22
+
23
+ - `repo-local` -- Fix lives entirely in project files, source code, or local configuration. The developer can apply it without side effects outside the repo.
24
+ - `package-manager` -- Requires CocoaPods or SPM configuration changes that may have broad side effects (e.g., linkage mode, dependency restructuring). These should be benchmarked before and after.
25
+ - `xcode-behavior` -- Observed cost is driven by Xcode internals and is not suppressible from the project. Report the finding for awareness but do not promise a fix.
26
+ - `upstream` -- Requires changes in a third-party dependency or external tool. The developer cannot fix it locally.
27
+
28
+ ## Suggested Optional Fields
29
+
30
+ - `scope`
31
+ - `affected_files`
32
+ - `affected_targets`
33
+ - `affected_packages`
34
+ - `implementation_notes`
35
+ - `risk_level`
36
+
37
+ ## JSON Example
38
+
39
+ ```json
40
+ {
41
+ "recommendations": [
42
+ {
43
+ "title": "Guard a release-only symbol upload script",
44
+ "wait_time_impact": "Expected to reduce your incremental build by approximately 6 seconds.",
45
+ "actionability": "repo-local",
46
+ "category": "project",
47
+ "observed_evidence": [
48
+ "Incremental builds spend 6.3 seconds in a run script phase.",
49
+ "The script runs for Debug builds even though the output is only needed in Release."
50
+ ],
51
+ "estimated_impact": "High incremental-build improvement",
52
+ "confidence": "High",
53
+ "approval_required": true,
54
+ "benchmark_verification_status": "Not yet verified",
55
+ "scope": "Target build phase",
56
+ "risk_level": "Low"
57
+ }
58
+ ]
59
+ }
60
+ ```
61
+
62
+ ## Markdown Rendering Guidance
63
+
64
+ When rendering for human review, preserve the same field order:
65
+
66
+ 1. title
67
+ 2. wait-time impact
68
+ 3. actionability
69
+ 4. observed evidence
70
+ 5. estimated impact
71
+ 6. confidence
72
+ 7. approval required
73
+ 8. benchmark verification status
74
+
75
+ That makes it easier for the developer to approve or reject specific items quickly.
76
+
77
+ ## Verification Status Values
78
+
79
+ Recommended values:
80
+
81
+ - `Not yet verified`
82
+ - `Queued for verification`
83
+ - `Verified improvement`
84
+ - `No measurable improvement`
85
+ - `Inconclusive due to benchmark noise`
@@ -0,0 +1,105 @@
1
+ # SPM Analysis Checks
2
+
3
+ Use this reference when package dependencies or package plugins are suspected build bottlenecks.
4
+
5
+ ## Package Graph Checks
6
+
7
+ - Identify large umbrella packages that trigger widespread rebuilds.
8
+ - Look for dependency layering that forces many downstream targets to recompile.
9
+ - Flag local package arrangements that cause broad invalidation after small edits.
10
+
11
+ ## Package Plugin Checks
12
+
13
+ - List build-tool and command plugins involved in the build.
14
+ - Measure whether plugins run during incremental builds even when no relevant input changed.
15
+ - Call out plugins that return quickly but still add fixed overhead to every build.
16
+
17
+ ## Package Reference Verification
18
+
19
+ - Before including any local package in a build-time recommendation, confirm it appears in the project's `XCLocalSwiftPackageReference` section of `project.pbxproj`.
20
+ - A package existing under `Vendor/` or as a directory in the repo does not mean it is linked. Only referenced packages affect build time.
21
+ - For remote packages, confirm the `XCRemoteSwiftPackageReference` entry exists and at least one `XCSwiftPackageProductDependency` links its product to a target.
22
+
23
+ ## Version Pin Feasibility
24
+
25
+ - When recommending a switch from `branch:` to a tagged version, verify tags exist via `git ls-remote --tags <url>`.
26
+ - If no tags exist, recommend pinning to a specific `revision:` hash for deterministic resolution.
27
+ - Note the distinction: branch pins force network checks on every fresh resolve; revision pins are fully deterministic but do not benefit from semver range resolution.
28
+
29
+ ## Binary And Remote Dependency Checks
30
+
31
+ - Note binary target size and extraction overhead for clean environments.
32
+ - Highlight remote checkout or fetch costs that matter for CI or fresh machines.
33
+ - Compare remote vs local package tradeoffs when iteration speed matters more than distribution convenience.
34
+
35
+ ## Module Variant Checks
36
+
37
+ - Look for the same dependency module being built with different options.
38
+ - Compare macros, language mode, and configuration-sensitive options across dependents.
39
+ - Prefer configuration alignment when it reduces repeated module builds safely.
40
+
41
+ ## Layered Architecture Validation
42
+
43
+ - Enforce a clear dependency direction: Common/Core --> Services/Domain --> Features/UI. Dependencies must flow in one direction only (inward/downward).
44
+ - Features should never depend on each other directly. If two features share types, move those types to a lower-layer module.
45
+ - Validate that `Package.swift` target dependency lists match the intended layer hierarchy.
46
+
47
+ ## Circular Dependency Detection
48
+
49
+ - SPM supports cyclic *package* dependencies (since May 2024) but not cyclic *target* dependencies.
50
+ - Circular module dependencies should always be refactored: extract the shared contract (protocols, DTOs) into a separate module that both sides depend on.
51
+ - Check for hidden cycles through transitive dependencies by tracing the full dependency graph.
52
+
53
+ ## Module Sizing Guidance
54
+
55
+ - Modules larger than roughly 200 files increase incremental build scope unnecessarily -- a single file change recompiles more than needed.
56
+ - Recommend splitting oversized modules by feature area or responsibility.
57
+ - Each module should have a clear, single-purpose responsibility. If a module's name requires "And" or "Utils" to describe, it likely needs splitting.
58
+
59
+ ## Transitive Dependency Minimization
60
+
61
+ - Each module should depend only on what it directly uses. Unnecessary transitive dependencies widen the rebuild surface.
62
+ - Avoid "umbrella" modules that re-export everything via `@_exported import` -- they create hidden dependency chains where a change in any re-exported module triggers rebuilds in all importers.
63
+ - Use `@_exported import` sparingly and only for genuine convenience wrappers.
64
+
65
+ ## Interface/Implementation Separation
66
+
67
+ - Define protocols and public types in lightweight "interface" modules (e.g., `NetworkingInterface`).
68
+ - Put implementations in separate modules (e.g., `NetworkingImpl`).
69
+ - Feature modules compile against the interface without waiting for the full implementation to build, improving parallelism.
70
+ - This pattern is most valuable when the implementation module has many files or heavy dependencies that would block downstream compilation.
71
+
72
+ ## Test Target Isolation
73
+
74
+ - Test targets should depend on the module under test, not the entire app target. Depending on the app target forces a full app build before tests can compile.
75
+ - Shared test utilities (mocks, fixtures, helpers) belong in a dedicated `TestHelpers` module rather than being duplicated across test targets.
76
+ - Keep test-only dependencies out of production target dependency lists.
77
+
78
+ ## Swift Macro Rebuild Impact
79
+
80
+ - Projects that heavily use Swift macros (e.g., TCA, swift-syntax-based libraries) are susceptible to incremental build cascading where a trivial change rebuilds most of the app.
81
+ - Macro expansion can invalidate downstream modules even when the expanded output has not changed, because the build system treats the macro input as a dependency.
82
+ - Check whether `swift-syntax` is building universally (all architectures) when no prebuilt binary is available. This adds significant overhead to clean builds and CI. Verify with the build log whether the `swift-syntax` target compiles for more architectures than `ONLY_ACTIVE_ARCH` would suggest.
83
+ - If macro-heavy packages dominate incremental build time, consider whether the macro-using code can be isolated into fewer, more stable modules to limit the invalidation blast radius.
84
+
85
+ ## Multi-Platform Build Multiplication
86
+
87
+ - Adding a secondary platform target (e.g., watchOS, macOS Catalyst) can cause shared SPM packages to build multiple times -- once per platform and architecture combination.
88
+ - A project with iOS and watchOS targets may build shared packages 3x: iOS arm64, iOS x86_64 (simulator), and watchOS arm64.
89
+ - Check the build log for duplicate `SwiftCompile`, `SwiftEmitModule`, and `ScanDependencies` tasks for the same package across different platform/architecture slices.
90
+ - If multi-platform multiplication is a significant contributor, consider whether secondary platform targets can use a subset of shared packages, or whether packages can be prebuilt as binary targets for secondary platforms.
91
+
92
+ ## CI-Specific Checks
93
+
94
+ - Fresh checkout cost
95
+ - plugin invocation cost
96
+ - cache hit sensitivity
97
+ - redundant package resolution work
98
+
99
+ ## Recommendation Prioritization
100
+
101
+ Qualify every estimated impact with wall-clock framing. High-priority items should be those likely to reduce the developer's actual wait time, not just cumulative task totals. If the impact on wait time is uncertain, say so.
102
+
103
+ - High: package plugins or graph structure repeatedly inflating incremental builds, circular dependencies, umbrella re-exports causing cascading rebuilds, Swift macro cascading that causes near-full rebuilds from trivial changes.
104
+ - Medium: configuration drift that causes duplicate module variants, oversized modules, missing interface/implementation separation, multi-platform build multiplication, `swift-syntax` building universally without prebuilt binary.
105
+ - Low: clean-environment checkout costs that barely affect local iteration, minor transitive dependency cleanup.
@@ -0,0 +1,118 @@
1
+ #!/usr/bin/env python3
2
+
3
+ """Scan a project.pbxproj for branch-pinned SPM dependencies and check tag availability."""
4
+
5
+ import argparse
6
+ import json
7
+ import re
8
+ import subprocess
9
+ import sys
10
+ from pathlib import Path
11
+ from typing import Dict, List, Optional
12
+
13
+
14
+ _PKG_REF_RE = re.compile(
15
+ r"(/\*\s*XCRemoteSwiftPackageReference\s+\"(?P<name>[^\"]+)\"\s*\*/\s*=\s*\{[^}]*?"
16
+ r"repositoryURL\s*=\s*\"(?P<url>[^\"]+)\"[^}]*?"
17
+ r"requirement\s*=\s*\{(?P<req>[^}]*)\})",
18
+ re.DOTALL,
19
+ )
20
+
21
+ _KIND_RE = re.compile(r"kind\s*=\s*(\w+)\s*;")
22
+ _BRANCH_RE = re.compile(r"branch\s*=\s*(\w+)\s*;")
23
+
24
+
25
+ def parse_args() -> argparse.Namespace:
26
+ parser = argparse.ArgumentParser(
27
+ description="Check branch-pinned SPM dependencies for available tags."
28
+ )
29
+ parser.add_argument(
30
+ "--project",
31
+ required=True,
32
+ help="Path to the .xcodeproj directory",
33
+ )
34
+ parser.add_argument(
35
+ "--json",
36
+ action="store_true",
37
+ help="Output results as JSON",
38
+ )
39
+ return parser.parse_args()
40
+
41
+
42
+ def find_branch_pins(pbxproj: str) -> List[Dict[str, str]]:
43
+ results: List[Dict[str, str]] = []
44
+ for match in _PKG_REF_RE.finditer(pbxproj):
45
+ name = match.group("name")
46
+ url = match.group("url")
47
+ req = match.group("req")
48
+ kind_match = _KIND_RE.search(req)
49
+ if not kind_match:
50
+ continue
51
+ kind = kind_match.group(1)
52
+ if kind != "branch":
53
+ continue
54
+ branch_match = _BRANCH_RE.search(req)
55
+ branch = branch_match.group(1) if branch_match else "unknown"
56
+ results.append({"name": name, "url": url, "branch": branch})
57
+ return results
58
+
59
+
60
+ def check_tags(url: str) -> List[str]:
61
+ try:
62
+ result = subprocess.run(
63
+ ["git", "ls-remote", "--tags", url],
64
+ capture_output=True,
65
+ text=True,
66
+ timeout=15,
67
+ )
68
+ if result.returncode != 0:
69
+ return []
70
+ tags: List[str] = []
71
+ for line in result.stdout.strip().splitlines():
72
+ ref = line.split("\t")[-1] if "\t" in line else ""
73
+ if ref.startswith("refs/tags/") and not ref.endswith("^{}"):
74
+ tags.append(ref.replace("refs/tags/", ""))
75
+ return tags
76
+ except (subprocess.TimeoutExpired, FileNotFoundError):
77
+ return []
78
+
79
+
80
+ def main() -> int:
81
+ args = parse_args()
82
+ pbxproj_path = Path(args.project) / "project.pbxproj"
83
+ if not pbxproj_path.exists():
84
+ sys.stderr.write(f"Not found: {pbxproj_path}\n")
85
+ return 1
86
+
87
+ pbxproj = pbxproj_path.read_text()
88
+ pins = find_branch_pins(pbxproj)
89
+
90
+ if not pins:
91
+ print("No branch-pinned SPM dependencies found.")
92
+ return 0
93
+
94
+ results: List[Dict] = []
95
+ for pin in pins:
96
+ tags = check_tags(pin["url"])
97
+ entry = {
98
+ "name": pin["name"],
99
+ "url": pin["url"],
100
+ "branch": pin["branch"],
101
+ "tags_available": len(tags) > 0,
102
+ "latest_tags": tags[-5:] if tags else [],
103
+ }
104
+ results.append(entry)
105
+
106
+ if args.json:
107
+ print(json.dumps(results, indent=2))
108
+ else:
109
+ for r in results:
110
+ status = "tags available" if r["tags_available"] else "no tags (pin to revision)"
111
+ latest = f" (latest: {', '.join(r['latest_tags'])})" if r["latest_tags"] else ""
112
+ print(f" {r['name']}: branch={r['branch']} -> {status}{latest}")
113
+
114
+ return 0
115
+
116
+
117
+ if __name__ == "__main__":
118
+ raise SystemExit(main())