Skip to content

Commit bfed6ec

Browse files
authored
Merge pull request #106 from mihaelamj/feat/99-availability
## Summary - Add platform availability filtering for all 5 Apple platforms (iOS, macOS, tvOS, watchOS, visionOS) - Implement `cupertino fetch --type availability` to fetch API availability data from Apple's documentation API - Add `--min-ios`, `--min-macos`, `--min-tvos`, `--min-watchos`, `--min-visionos` filters to CLI search and MCP tools ## Features ### Availability Fetching - New `fetch --type availability` command fetches minimum platform versions from Apple's API - Concurrent fetching with configurable concurrency (default 50 requests) - Progress reporting with statistics (success rate, duration, documents processed) - Skip existing data with `--skip-existing` flag for incremental updates ### Search Filtering - Filter search results by minimum platform version - Works with CLI: `cupertino search "View" --min-ios 15.0` - Works with MCP tool: `search_docs` with `min_ios`, `min_macos`, `min_tvos`, `min_watchos`, `min_visionos` parameters - Results show availability info per platform ### Code Quality - Added `FrameworkAvailability` struct to replace large tuples - Fixed SwiftLint violations (identifier_name, line_length, large_tuple) - Comprehensive test coverage for availability type
2 parents 8f2e1da + 5c5bee0 commit bfed6ec

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+3379
-54
lines changed

CHANGELOG.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,35 @@
1+
## 0.6.0 (2025-12-12)
2+
3+
### Added
4+
- **Platform Availability Support** (#99)
5+
- `cupertino fetch --type availability` - Fetch platform version data for all docs
6+
- Availability tracked for all sources: apple-docs, sample-code, archive, swift-evolution, swift-book, hig
7+
- Search filtering by `--min-ios`, `--min-macos`, `--min-tvos`, `--min-watchos`, `--min-visionos` (CLI and MCP `search_docs` tool)
8+
- `save` command now warns if docs don't have availability data
9+
- Schema v7: availability columns in docs_metadata and sample_code_metadata
10+
11+
### Availability Sources
12+
| Source | Strategy |
13+
|--------|----------|
14+
| apple-docs | API fetch + fallbacks |
15+
| sample-code | Derives from framework |
16+
| apple-archive | Derives from framework |
17+
| swift-evolution | Swift version mapping |
18+
| swift-book/hig | Universal (all platforms) |
19+
20+
### Documentation
21+
- Added `docs/commands/search/option (--)/min-ios.md`
22+
- Added `docs/commands/search/option (--)/min-macos.md`
23+
- Added `docs/commands/search/option (--)/min-tvos.md`
24+
- Added `docs/commands/search/option (--)/min-watchos.md`
25+
- Added `docs/commands/search/option (--)/min-visionos.md`
26+
- Updated search command docs with availability filtering options
27+
28+
### Related Issues
29+
- Closes #99
30+
31+
---
32+
133
## 0.5.0 (2025-12-11)
234

335
**Why minor bump?** The `cupertino release` command was removed from the public CLI. Users who had scripts calling `cupertino release` will need to update them. This is a breaking change for maintainer workflows.

Packages/Package.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ let macOSOnlyProducts: [Product] = [
2424
.singleTargetLibrary("SampleIndex"),
2525
.singleTargetLibrary("Services"),
2626
.singleTargetLibrary("Resources"),
27+
.singleTargetLibrary("Availability"),
2728
.singleTargetLibrary("MCPSupport"),
2829
.singleTargetLibrary("SearchToolProvider"),
2930
.singleTargetLibrary("MCPClient"),
@@ -178,6 +179,15 @@ let targets: [Target] = {
178179
dependencies: ["RemoteSync", "TestSupport"]
179180
)
180181

182+
let availabilityTarget = Target.target(
183+
name: "Availability",
184+
dependencies: []
185+
)
186+
let availabilityTestsTarget = Target.testTarget(
187+
name: "AvailabilityTests",
188+
dependencies: ["Availability", "TestSupport"]
189+
)
190+
181191
let cliTarget = Target.executableTarget(
182192
name: "CLI",
183193
dependencies: [
@@ -189,6 +199,7 @@ let targets: [Target] = {
189199
"Services",
190200
"Logging",
191201
"RemoteSync",
202+
"Availability",
192203
// MCP dependencies (for mcp serve command)
193204
"MCP",
194205
"MCPSupport",
@@ -296,6 +307,8 @@ let targets: [Target] = {
296307
mcpClientTestsTarget,
297308
remoteSyncTarget,
298309
remoteSyncTestsTarget,
310+
availabilityTarget,
311+
availabilityTestsTarget,
299312
testSupportTarget,
300313
cliTarget,
301314
tuiTarget,
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import Foundation
2+
3+
/// Namespace for availability-related types
4+
public enum Availability {
5+
// Namespace root - types defined in extensions
6+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import Foundation
2+
3+
// MARK: - Availability Errors
4+
5+
/// Errors that can occur during availability fetching
6+
public enum AvailabilityError: Error, LocalizedError, Sendable {
7+
/// Network request failed
8+
case networkError(Error)
9+
10+
/// Request timed out
11+
case timeout
12+
13+
/// API returned 404 (symbol not found)
14+
case notFound(String)
15+
16+
/// Invalid response from API
17+
case invalidResponse
18+
19+
/// Rate limited by API
20+
case rateLimited
21+
22+
/// No documentation directory found
23+
case noDocumentationFound
24+
25+
/// Failed to parse JSON
26+
case jsonParseError(Error)
27+
28+
/// Failed to write updated file
29+
case writeError(Error)
30+
31+
public var errorDescription: String? {
32+
switch self {
33+
case .networkError(let error):
34+
return "Network error: \(error.localizedDescription)"
35+
case .timeout:
36+
return "Request timed out"
37+
case .notFound(let symbol):
38+
return "Symbol not found: \(symbol)"
39+
case .invalidResponse:
40+
return "Invalid response from Apple API"
41+
case .rateLimited:
42+
return "Rate limited by Apple API"
43+
case .noDocumentationFound:
44+
return "No documentation directory found"
45+
case .jsonParseError(let error):
46+
return "JSON parse error: \(error.localizedDescription)"
47+
case .writeError(let error):
48+
return "Failed to write file: \(error.localizedDescription)"
49+
}
50+
}
51+
}

0 commit comments

Comments
 (0)