diff --git a/CLAUDE.md b/CLAUDE.md index 633b8fb8..294bdae1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -461,6 +461,28 @@ For detailed schema workflows and integration: - **AI Schema Workflow** (`Examples/CelestraCloud/.claude/AI_SCHEMA_WORKFLOW.md`) - Comprehensive guide for understanding, designing, modifying, and validating CloudKit schemas with text-based tools - **Quick Reference** (`Examples/SCHEMA_QUICK_REFERENCE.md`) - One-page cheat sheet with syntax, patterns, cktool commands, and troubleshooting +## Examples + +The `Examples/` directory contains working applications that dogfood MistKit-under-development (see also the README "Examples" list). These are MistKit-dev test beds, not end-user deployment templates. + +### BushelCloud — the canonical MistKit pattern demonstration + +`Examples/BushelCloud/` is the most complete reference implementation of MistKit's core patterns — the backend that syncs macOS restore images, Xcode, and Swift versions for the [Bushel app](https://getbushel.app): + +- **Server-to-Server authentication** — loading an ECDSA `.pem` key and wiring `ServerToServerAuthManager` into `CloudKitService` (`Sources/BushelCloudKit/CloudKit/BushelCloudKitService.swift`, `PEMValidator.swift`). +- **Batch / chunked record operations** — working within CloudKit's 200-operations-per-request limit and aggregating results across batches (`CloudKit/SyncEngine.swift`, `CloudKit/BushelCloudKitService.swift`). +- **Multi-source data integration** — fetching and deduplicating from many upstream APIs (`DataSources/` — IPSW, MESU, AppleDB, XcodeReleases, SwiftVersion, …; `DataSourcePipeline+Deduplication.swift`). +- **CloudKit reference usage** — creating and resolving reference fields between record types (`DataSources/DataSourcePipeline+ReferenceResolution.swift`, `Extensions/XcodeVersionRecord+CloudKit.swift`). +- **Cross-platform logging** — swift-log with MistKit's subsystem organization (`Configuration/BushelConfiguration.swift`). + +### CelestraCloud — query filtering, sorting & web etiquette + +`Examples/CelestraCloud/` is a command-line RSS reader (backend for the [Celestra app](https://celestr.app)) demonstrating MistKit's `QueryFilter`/`QuerySort` APIs, GUID-based duplicate detection, and respectful HTTP client patterns. See its own `CLAUDE.md`. + +### MistDemo — interactive auth & endpoint demo + +`Examples/MistDemo/` is a CLI + App + Web demo exercising the beta.2 endpoint surface with web-auth token capture. See the project-level "MistDemo Commands" section above. + ## Import Conventions Every `import` statement must carry an explicit access modifier — `internal import X` or `public import X`. Bare `import X` is forbidden. Default to `internal`; use `public import` only when the module's types appear in this file's `public` API (e.g. `public import HTTPTypes` where `HTTPRequest` is part of a `public` signature). diff --git a/Examples/CelestraCloud/CHANGELOG.md b/Examples/CelestraCloud/CHANGELOG.md index 484bbf72..66700b48 100644 --- a/Examples/CelestraCloud/CHANGELOG.md +++ b/Examples/CelestraCloud/CHANGELOG.md @@ -70,7 +70,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Technical Details - **Platform**: macOS 26+ (Swift 6.2) - **Concurrency**: Full Swift 6 concurrency support with strict checking -- **Dependencies**: MistKit 1.0.0-alpha.3, SyndiKit 0.6.1, ArgumentParser, swift-log +- **Dependencies**: MistKit 1.0.0-beta.2, SyndiKit 0.6.1, ArgumentParser, swift-log - **CloudKit**: Public database with Feed and Article record types - **Schema**: Text-based .ckdb schema with cktool deployment diff --git a/README.md b/README.md index af82de56..12fdd2c4 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ Add MistKit to your `Package.swift`: ```swift dependencies: [ - .package(url: "https://github.com/brightdigit/MistKit.git", from: "1.0.0-beta.1") + .package(url: "https://github.com/brightdigit/MistKit.git", from: "1.0.0-beta.2") ] ``` @@ -290,6 +290,62 @@ do { ### Advanced Usage +#### More Operations + +Beyond querying and CRUD, MistKit covers zones, subscriptions, push tokens, and +asset re-referencing. Every call takes an explicit `database:`. + +```swift +// Zones +let zone = try await service.createZone( + zoneName: "Notes", + database: .private +) +try await service.deleteZone(zoneName: "Notes", database: .private) + +// Subscriptions +let subs = try await service.listSubscriptions(database: .private) +let one = try await service.lookupSubscriptions(ids: ["sub-1"], database: .private) +// Create/update/delete via service.modifySubscriptions(_:database:) +// (takes [SubscriptionOperation], returns [SubscriptionResult]). + +// APNs push tokens +let token = try await service.createAPNsToken( + environment: .development, + database: .private +) +try await service.registerAPNsToken( + token.apnsToken, + environment: .development, + database: .private +) + +// Re-reference existing CDN assets without re-uploading bytes +let assets = try await service.rereferenceAssets( + [(recordName: "rec-1", fieldName: "photo")], + database: .private +) +``` + +#### Auto-Chunking Conveniences + +CloudKit caps batch requests at 200 items. `lookupAllRecords` and the +`lookupInfos:` form of `discoverAllUserIdentities` split oversized inputs into +≤`maxRecordsPerRequest` (200) batches automatically and concatenate the results +in input order — no manual chunking required. + +```swift +let records = try await service.lookupAllRecords( + recordNames: thousandsOfNames, // chunked into 200-item requests + database: .private +) + +let identities = try await service.discoverAllUserIdentities( + lookupInfos: manyLookupInfos, + batchSize: 200 +) +``` + #### HTTP Transport Non-WASI platforms default to `URLSessionTransport` — no transport plumbing is @@ -424,23 +480,27 @@ MistKit is released under the MIT License. See [LICENSE](LICENSE) for details. - [x] CI updates for May 2026 ([#277](https://github.com/brightdigit/MistKit/pull/277)) ✅ - [x] Fail lint job when any command fails ([#303](https://github.com/brightdigit/MistKit/pull/303)) ✅ -### v1.0.0-alpha.X +### v1.0.0-beta.2 + +- [x] [Referencing Existing Assets (assets/rereference)](https://github.com/brightdigit/MistKit/issues/31) ✅ +- [x] [Modifying Zones (zones/modify)](https://github.com/brightdigit/MistKit/issues/45) ✅ +- [x] [Fetching Subscriptions (subscriptions/list)](https://github.com/brightdigit/MistKit/issues/49) ✅ +- [x] [Fetching Subscriptions by Identifier (subscriptions/lookup)](https://github.com/brightdigit/MistKit/issues/50) ✅ +- [x] [Modifying Subscriptions (subscriptions/modify)](https://github.com/brightdigit/MistKit/issues/51) ✅ +- [x] [Creating APNs Tokens (tokens/create)](https://github.com/brightdigit/MistKit/issues/52) ✅ +- [x] [Registering Tokens (tokens/register)](https://github.com/brightdigit/MistKit/issues/53) ✅ +- [x] [Fetching Users by Email (users/lookup/email)](https://github.com/brightdigit/MistKit/issues/34) ✅ *(Apple-deprecated — prefer `discoverAllUserIdentities`)* +- [x] [Fetching Users by Record Name (users/lookup/id)](https://github.com/brightdigit/MistKit/issues/35) ✅ *(Apple-deprecated — prefer `discoverAllUserIdentities`)* +- [x] Auto-chunking conveniences for batch operations ([#389](https://github.com/brightdigit/MistKit/pull/389)) ✅ + +### Backlog / Post-beta - [ ] [Discovering All User Identities (GET users/discover)](https://github.com/brightdigit/MistKit/issues/28) -- [ ] [Referencing Existing Assets (assets/rereference)](https://github.com/brightdigit/MistKit/issues/31) - [ ] [Fetching Contacts (users/lookup/contacts)](https://github.com/brightdigit/MistKit/issues/33) -- [ ] [Fetching Users by Email (users/lookup/email)](https://github.com/brightdigit/MistKit/issues/34) -- [ ] [Fetching Users by Record Name (users/lookup/id)](https://github.com/brightdigit/MistKit/issues/35) - [ ] [Fetching Record Information (records/resolve)](https://github.com/brightdigit/MistKit/issues/41) - [ ] [Accepting Share Records (records/accept)](https://github.com/brightdigit/MistKit/issues/42) - [ ] [Fetching Database Changes (changes/database)](https://github.com/brightdigit/MistKit/issues/46) -- [ ] [Modifying Zones (zones/modify)](https://github.com/brightdigit/MistKit/issues/45) - [ ] [Fetching Record Zone Changes (changes/zone)](https://github.com/brightdigit/MistKit/issues/47) -- [ ] [Fetching Subscriptions (subscriptions/list)](https://github.com/brightdigit/MistKit/issues/49) -- [ ] [Fetching Subscriptions by Identifier (subscriptions/lookup)](https://github.com/brightdigit/MistKit/issues/50) -- [ ] [Modifying Subscriptions (subscriptions/modify)](https://github.com/brightdigit/MistKit/issues/51) -- [ ] [Creating APNs Tokens (tokens/create)](https://github.com/brightdigit/MistKit/issues/52) -- [ ] [Registering Tokens (tokens/register)](https://github.com/brightdigit/MistKit/issues/53) - [ ] [Feature: Add custom CloudKit zone support for queries](https://github.com/brightdigit/MistKit/issues/146) ### v1.0.0 diff --git a/ReleaseNotes.md b/ReleaseNotes.md index c6087bf4..7807bb29 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -1,3 +1,32 @@ +## 1.0.0-beta.2 + +### Subscriptions & Push Notifications +* Push Notifications & Subscriptions epic — `listSubscriptions`, `lookupSubscriptions`, `modifySubscriptions`, `createAPNsToken`, `registerAPNsToken` by @leogdion in https://github.com/brightdigit/MistKit/pull/381 + +### Zones +* Zone API: `createZone`, `deleteZone`, `fetchAllZoneChanges` by @leogdion in https://github.com/brightdigit/MistKit/pull/367 +* `list-zones`, `modify-zones`, discover, and validate by @leogdion in https://github.com/brightdigit/MistKit/pull/368 + +### Assets +* Implement `assets/rereference` endpoint and API by @leogdion in https://github.com/brightdigit/MistKit/pull/393 + +### Batch Conveniences +* Auto-chunking conveniences for batch operations (`lookupAllRecords`, `discoverAllUserIdentities(lookupInfos:batchSize:)`) by @leogdion in https://github.com/brightdigit/MistKit/pull/389 + +### Correctness & Safety +* Tag and validate ambiguous `FieldValue` scalar types (`TIMESTAMP`, `BYTES`, `DOUBLE`) by @leogdion in https://github.com/brightdigit/MistKit/pull/377 +* Make response→domain conversion failures loud; add `RecordResult` by @leogdion in https://github.com/brightdigit/MistKit/pull/372 +* Pre-1.0.0 correctness & safety hardening by @leogdion in https://github.com/brightdigit/MistKit/pull/357 +* Style & error audit: explicit import access + scoped flake gates by @leogdion in https://github.com/brightdigit/MistKit/pull/363 + +### Tooling, MistDemo & Docs +* Scaffold MistDemo (CLI + App + Web) for v1.0.0-beta.2 endpoints by @leogdion in https://github.com/brightdigit/MistKit/pull/371 +* Wire landed MistKit endpoints into the MistDemo web app by @leogdion in https://github.com/brightdigit/MistKit/pull/396 +* `setup-mistkit`: pin to resolved revision by @leogdion in https://github.com/brightdigit/MistKit/pull/380 +* Enable MistDemo integration workflow on `claude/**` branches by @leogdion in https://github.com/brightdigit/MistKit/pull/374 + +**Full Changelog**: https://github.com/brightdigit/MistKit/compare/1.0.0-beta.1...1.0.0-beta.2 + ## 1.0.0-beta.1 ### Querying & Sync