From 31781e074a65110da07d49fdcf6a52d61b70b42e Mon Sep 17 00:00:00 2001 From: Aki Shinagawa Date: Fri, 5 Jul 2024 09:34:03 -0700 Subject: [PATCH 1/3] [IOS-6800] Support in-feed Placement (#4) This commit will update adapter code to support in-feed ad type. IOS-6800 --- .../Vungle/ISVungleAdapter/ISVungleAdapter.h | 1 - .../Vungle/ISVungleAdapter/ISVungleAdapter.m | 52 ++++++++----------- .../ISVungleAdapter/ISVungleBannerDelegate.h | 5 +- .../ISVungleAdapter/ISVungleBannerDelegate.m | 33 ++++++------ 4 files changed, 40 insertions(+), 51 deletions(-) diff --git a/Adapters/Vungle/ISVungleAdapter/ISVungleAdapter.h b/Adapters/Vungle/ISVungleAdapter/ISVungleAdapter.h index e28809b6..86e673f1 100644 --- a/Adapters/Vungle/ISVungleAdapter/ISVungleAdapter.h +++ b/Adapters/Vungle/ISVungleAdapter/ISVungleAdapter.h @@ -28,5 +28,4 @@ static NSString * Githash = @""; @import WebKit; @interface ISVungleAdapter : ISBaseAdapter - @end diff --git a/Adapters/Vungle/ISVungleAdapter/ISVungleAdapter.m b/Adapters/Vungle/ISVungleAdapter/ISVungleAdapter.m index 0a682218..9f0d9633 100644 --- a/Adapters/Vungle/ISVungleAdapter/ISVungleAdapter.m +++ b/Adapters/Vungle/ISVungleAdapter/ISVungleAdapter.m @@ -639,13 +639,10 @@ - (void)loadBannerInternal:(NSString *)placementId [self.bannerPlacementIdToSmashDelegate setObject:delegate forKey:placementId]; - // create banner container view + // create Vungle banner view dispatch_async(dispatch_get_main_queue(), ^{ - UIView *containerView = [[UIView alloc] initWithFrame:[self getBannerFrame:size]]; - // initialize banner ad delegate ISVungleBannerDelegate *bannerAdDelegate = [[ISVungleBannerDelegate alloc] initWithPlacementId:placementId - containerView:containerView andDelegate:delegate]; [self.bannerPlacementIdToVungleAdDelegate setObject:bannerAdDelegate @@ -654,17 +651,21 @@ - (void)loadBannerInternal:(NSString *)placementId [self.bannerPlacementIdToAdSize setObject:size forKey:placementId]; + // calculate VungleAdSize + VungleAdSize *adSize = [self getBannerSize:size]; + // create vungle banner ad - VungleBanner *vungleBannerAd = [[VungleBanner alloc] initWithPlacementId:placementId - size:[self getBannerSize:size]]; - - vungleBannerAd.delegate = bannerAdDelegate; + VungleBannerView *vungleBannerView = [[VungleBannerView alloc] initWithPlacementId:placementId + vungleAdSize:adSize]; + + // set delegate + vungleBannerView.delegate = bannerAdDelegate; - [self.bannerPlacementIdToAd setObject:vungleBannerAd + [self.bannerPlacementIdToAd setObject:vungleBannerView forKey:placementId]; // load banner - [vungleBannerAd load:serverData]; + [vungleBannerView load:serverData]; }); } @@ -776,30 +777,19 @@ - (NSDictionary *)getBiddingDataWithPlacementId:(NSString *)placementId { return @{@"token": returnedToken}; } -- (BannerSize)getBannerSize:(ISBannerSize *)size { - if ([size.sizeDescription isEqualToString:@"RECTANGLE"]) { - return BannerSizeMrec; - } else if ([size.sizeDescription isEqualToString:@"SMART"]) { +- (VungleAdSize *)getBannerSize:(ISBannerSize *)size { + if ([size.sizeDescription isEqualToString:kSizeCustom]) { + return [VungleAdSize VungleAdSizeFromCGSize:CGSizeMake(size.width, size.height)]; + } else if ([size.sizeDescription isEqualToString:kSizeRectangle]) { + return [VungleAdSize VungleAdSizeMREC]; + } else if ([size.sizeDescription isEqualToString:kSizeLeaderboard]) { + return [VungleAdSize VungleAdSizeLeaderboard]; + } else if ([size.sizeDescription isEqualToString:kSizeSmart]) { if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { - return BannerSizeLeaderboard; + return [VungleAdSize VungleAdSizeLeaderboard]; } } - - return BannerSizeRegular; -} - -- (CGRect)getBannerFrame:(ISBannerSize *)size { - CGRect rect = CGRectMake(0, 0, 320, 50); - - if ([size.sizeDescription isEqualToString:@"RECTANGLE"]) { - rect = CGRectMake(0, 0, 300, 250); - } else if ([size.sizeDescription isEqualToString:@"SMART"]) { - if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { - rect = CGRectMake(0, 0, 728, 90); - } - } - - return rect; + return [VungleAdSize VungleAdSizeBannerRegular]; } @end diff --git a/Adapters/Vungle/ISVungleAdapter/ISVungleBannerDelegate.h b/Adapters/Vungle/ISVungleAdapter/ISVungleBannerDelegate.h index 26453fb1..f31a8984 100644 --- a/Adapters/Vungle/ISVungleAdapter/ISVungleBannerDelegate.h +++ b/Adapters/Vungle/ISVungleAdapter/ISVungleBannerDelegate.h @@ -11,14 +11,13 @@ NS_ASSUME_NONNULL_BEGIN -@interface ISVungleBannerDelegate : NSObject +@interface ISVungleBannerDelegate : NSObject @property (nonatomic, strong) NSString *placementId; -@property (nonatomic, strong) UIView *containerView; @property (nonatomic, weak) id delegate; +@property (nonatomic, assign) BOOL isAdloadSuccess; - (instancetype)initWithPlacementId:(NSString *)placementId - containerView:(UIView *)containerView andDelegate:(id)delegate; @end diff --git a/Adapters/Vungle/ISVungleAdapter/ISVungleBannerDelegate.m b/Adapters/Vungle/ISVungleAdapter/ISVungleBannerDelegate.m index e91ffb5b..2242a0c1 100644 --- a/Adapters/Vungle/ISVungleAdapter/ISVungleBannerDelegate.m +++ b/Adapters/Vungle/ISVungleAdapter/ISVungleBannerDelegate.m @@ -11,51 +11,52 @@ @implementation ISVungleBannerDelegate - (instancetype)initWithPlacementId:(NSString *)placementId - containerView:(UIView *)containerView andDelegate:(id)delegate { self = [super init]; if (self) { _placementId = placementId; - _containerView = containerView; _delegate = delegate; + _isAdloadSuccess = NO; } return self; } -#pragma mark - Banner Delegate +#pragma mark - VungleBannerView Delegate -- (void)bannerAdDidLoad:(VungleBanner * _Nonnull)banner { - LogAdapterDelegate_Internal(@"placementId = %@", self.placementId); - [self.delegate adapterBannerDidLoad:self.containerView]; - dispatch_async(dispatch_get_main_queue(), ^{ - [banner presentOn:self.containerView]; - }); +- (void)bannerAdDidLoad:(VungleBannerView * _Nonnull)bannerView { + LogAdapterDelegate_Internal(@"placementId = %@", self.placementId); + + self.isAdloadSuccess = YES; + [self.delegate adapterBannerDidLoad:bannerView]; } -- (void)bannerAdDidFailToLoad:(VungleBanner * _Nonnull)banner - withError:(NSError * _Nonnull)error { +- (void)bannerAdDidFail:(VungleBannerView * _Nonnull)bannerView + withError:(NSError * _Nonnull)error { LogAdapterDelegate_Internal(@"placementId = %@ error = %@", self.placementId, error); NSInteger errorCode = (error.code == kVungleNoFillErrorCode) ? ERROR_BN_LOAD_NO_FILL : error.code; NSError *bannerError = [NSError errorWithDomain:kAdapterName code:errorCode userInfo:@{NSLocalizedDescriptionKey:error.description}]; - - [self.delegate adapterBannerDidFailToLoadWithError:bannerError]; + if (self.isAdloadSuccess) { + [self.delegate adapterBannerDidFailToShowWithError:bannerError]; + } else { + [self.delegate adapterBannerDidFailToLoadWithError:bannerError]; + } } -- (void)bannerAdDidTrackImpression:(VungleBanner * _Nonnull)banner { +- (void)bannerAdDidTrackImpression:(VungleBannerView * _Nonnull)bannerView { LogAdapterDelegate_Internal(@"placementId = %@", self.placementId); [self.delegate adapterBannerDidShow]; } -- (void)bannerAdDidClick:(VungleBanner * _Nonnull)banner { +- (void)bannerAdDidClick:(VungleBannerView * _Nonnull)bannerView { LogAdapterDelegate_Internal(@"placementId = %@", self.placementId); [self.delegate adapterBannerDidClick]; } -- (void)bannerAdWillLeaveApplication:(VungleBanner * _Nonnull)banner { +- (void)bannerAdWillLeaveApplication:(VungleBannerView * _Nonnull)bannerView { LogAdapterDelegate_Internal(@"placementId = %@", self.placementId); [self.delegate adapterBannerWillLeaveApplication]; } From d55047cc768a3c85f5753067369c36d90834ab33 Mon Sep 17 00:00:00 2001 From: Mian Leow Date: Fri, 20 Mar 2026 21:58:50 -0700 Subject: [PATCH 2/3] feat: add claude-native knowledge layer Structured .claude/knowledge/ directory with architecture docs, conventions, ADRs, and extraction scripts for AI-assisted development. Co-Authored-By: Claude Opus 4.6 --- .claude/conventions.yml | 38 ++++++++++++++++++ .../adrs/001-is-base-adapter-pattern.md | 22 +++++++++++ .../adrs/002-xcframework-build-scripts.md | 25 ++++++++++++ .../knowledge/adrs/003-delegate-per-format.md | 23 +++++++++++ .claude/review-rules.yml | 29 ++++++++++++++ CLAUDE.md | 39 +++++++++++++++++++ 6 files changed, 176 insertions(+) create mode 100644 .claude/conventions.yml create mode 100644 .claude/knowledge/adrs/001-is-base-adapter-pattern.md create mode 100644 .claude/knowledge/adrs/002-xcframework-build-scripts.md create mode 100644 .claude/knowledge/adrs/003-delegate-per-format.md create mode 100644 .claude/review-rules.yml create mode 100644 CLAUDE.md diff --git a/.claude/conventions.yml b/.claude/conventions.yml new file mode 100644 index 00000000..95bb2ebb --- /dev/null +++ b/.claude/conventions.yml @@ -0,0 +1,38 @@ +conventions: + - id: adapter-structure + description: > + Each network adapter lives under Adapters/{Network}/IS{Network}Adapter/. + All adapters extend ISBaseAdapter. Each adapter has format-specific + delegate classes and a constants header. Per-adapter Podfile for + CocoaPods dependency management. + applies_to: "Adapters/**/*.{h,m}" + + - id: naming-conventions + description: > + Adapter class: IS{Network}Adapter. Delegate classes: + IS{Network}{Format}Delegate (e.g., ISVungleRewardedVideoDelegate). + Constants: IS{Network}Constants.h. All code is Objective-C following + Apple naming conventions. + applies_to: "Adapters/**/*.{h,m}" + + - id: ad-format-support + description: > + All adapters support Banner, Interstitial, and Rewarded Video. + Native Ads supported only by the Google adapter. Each format has + its own delegate class handling callbacks independently. + applies_to: "Adapters/**/*.m" + + - id: version-management + description: > + Adapter versions are managed per network. Version numbers and + SDK dependencies are declared in the adapter's Podfile and source. + Constants header typically contains version string. + applies_to: "Adapters/**/*" + + - id: xcframework-build + description: > + The build_XCFramework.sh script produces xcframework bundles + combining device and simulator architectures. This is the primary + distribution format for adapter binaries. Scripts use xcodebuild + archive and -create-xcframework. + applies_to: "**/*.sh" diff --git a/.claude/knowledge/adrs/001-is-base-adapter-pattern.md b/.claude/knowledge/adrs/001-is-base-adapter-pattern.md new file mode 100644 index 00000000..f760530b --- /dev/null +++ b/.claude/knowledge/adrs/001-is-base-adapter-pattern.md @@ -0,0 +1,22 @@ +# ADR-001: ISBaseAdapter Inheritance Pattern + +## Status +Accepted + +## Context +Unity LevelPlay (ironSource) mediates ads from 11 network SDKs on iOS. Each adapter must handle SDK initialization, ad format support declaration, and lifecycle management. A consistent base provides shared functionality. + +## Decision +All network adapters extend `ISBaseAdapter` provided by the ironSource SDK: +- `ISBaseAdapter` provides shared initialization, configuration, and format registration +- Each adapter class (`IS{Network}Adapter`) overrides methods for supported ad formats +- Adapter declares supported formats (Banner, Interstitial, Rewarded Video) via base class methods +- Format-specific behavior is delegated to dedicated delegate classes + +## Consequences +- Consistent adapter structure across all 11 networks +- ISBaseAdapter handles common mediation plumbing +- Adapters focus on network-specific SDK integration +- Base class updates from ironSource SDK affect all adapters +- Adapter must conform to base class lifecycle contract +- Adding native ads requires base class support (currently Google-only) diff --git a/.claude/knowledge/adrs/002-xcframework-build-scripts.md b/.claude/knowledge/adrs/002-xcframework-build-scripts.md new file mode 100644 index 00000000..538f6b84 --- /dev/null +++ b/.claude/knowledge/adrs/002-xcframework-build-scripts.md @@ -0,0 +1,25 @@ +# ADR-002: Automated XCFramework Build Scripts + +## Status +Accepted + +## Context +iOS adapters must support multiple architectures: arm64 for physical devices, x86_64 and arm64 for simulators (Intel and Apple Silicon Macs). Apple's xcframework format is required to bundle multiple architecture slices without conflicts. + +## Decision +Each adapter includes or shares a `build_XCFramework.sh` script that: +1. Cleans previous build artifacts +2. Archives for iOS device (arm64) using `xcodebuild archive` +3. Archives for iOS simulator (x86_64, arm64) using `xcodebuild archive` +4. Combines archives using `xcodebuild -create-xcframework` +5. Outputs the final `.xcframework` bundle + +Scripts are designed to be run from the adapter directory or project root. + +## Consequences +- Reproducible xcframework builds via a single script invocation +- Supports both Intel and Apple Silicon Mac simulators +- Scripts must be updated when Xcode build settings change +- xcframework is the standard Apple multi-architecture distribution format +- Enables binary distribution alongside CocoaPods source distribution +- Build scripts serve as documentation of the build process diff --git a/.claude/knowledge/adrs/003-delegate-per-format.md b/.claude/knowledge/adrs/003-delegate-per-format.md new file mode 100644 index 00000000..d9b18dab --- /dev/null +++ b/.claude/knowledge/adrs/003-delegate-per-format.md @@ -0,0 +1,23 @@ +# ADR-003: Format-Specific Delegate Classes + +## Status +Accepted + +## Context +Each ad format (Banner, Interstitial, Rewarded Video) has its own set of delegate callbacks from the network SDK. Implementing all delegates in the main adapter class would create large, complex files. Different formats have different lifecycle events (e.g., rewarded has reward callback, banner has resize). + +## Decision +Each ad format has a dedicated delegate class: +- `IS{Network}BannerDelegate` — handles banner load, display, click, resize +- `IS{Network}InterstitialDelegate` — handles interstitial load, show, close, click +- `IS{Network}RewardedVideoDelegate` — handles rewarded load, show, close, click, reward + +The main adapter class (`IS{Network}Adapter`) instantiates and coordinates delegates. A constants header (`IS{Network}Constants.h`) defines shared values. + +## Consequences +- Each delegate class has focused, single-format responsibility +- Main adapter class stays manageable as an orchestrator +- Easier to add new format support by adding a new delegate class +- Constants shared across delegates are centralized +- More files per adapter (adapter + 3 delegates + constants = 5 files minimum) +- Delegates must communicate with the adapter for shared state (e.g., init status) diff --git a/.claude/review-rules.yml b/.claude/review-rules.yml new file mode 100644 index 00000000..23b6b25f --- /dev/null +++ b/.claude/review-rules.yml @@ -0,0 +1,29 @@ +review_rules: + - path: "Adapters/**/*.{h,m}" + rules: + - Adapter must extend ISBaseAdapter + - All three ad formats (Banner, Interstitial, Rewarded Video) must be supported + - Format-specific delegate classes must be separate files + - Constants must be defined in a dedicated IS{Network}Constants.h header + - Memory management must be correct (no retain cycles in delegate patterns) + - All callbacks must dispatch on the main thread + + - path: "Adapters/**/*Delegate*.{h,m}" + rules: + - Each delegate class handles exactly one ad format + - Must implement all required delegate methods for the format + - Must forward events correctly to the ironSource mediation layer + - Must handle error cases and report them via appropriate callbacks + + - path: "**/Podfile" + rules: + - Must specify the correct ironSource SDK dependency version + - Must specify the correct third-party network SDK version + - Platform version must be iOS 12.0 or higher + + - path: "**/*.sh" + rules: + - xcframework build scripts must handle both device and simulator slices + - Must use xcodebuild archive and -create-xcframework + - Must clean previous build artifacts before rebuilding + - Output paths must be consistent and documented diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..1a7c450a --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,39 @@ +# LevelPlay iOS Adapters + +## Overview +Unity LevelPlay (ironSource) iOS mediation adapters. Contains 11 network adapters for serving ads through the ironSource mediation platform. + +## Language +- **Objective-C** (100%) + +## Build System +- **CocoaPods**: Per-adapter Podfile for dependency management +- **Xcode projects**: Per-adapter build targets +- **xcframework build scripts**: `build_XCFramework.sh` for multi-architecture framework builds + +## Architecture +- Directory structure: `Adapters/{Network}/IS{Network}Adapter/` +- All adapters extend `ISBaseAdapter` base class +- Format-specific delegate classes per adapter +- Pattern: `IS{Network}Adapter.h/.m` + format delegates + constants file + +## Ad Formats +- Banner (all adapters) +- Interstitial (all adapters) +- Rewarded Video (all adapters) +- Native Ads (Google adapter only) + +## Vungle Adapter +- Adapter version: v4.3.36 +- VungleAds SDK: 7.4.0 + +## Platform Requirements +- Min iOS: 12.0 +- IronSource SDK: 8.2.0.0 + +## Key Conventions +- Adapter naming: `IS{Network}Adapter` +- ISBaseAdapter inheritance for shared lifecycle +- Delegate-per-format pattern (separate delegate class per ad format) +- Constants defined in dedicated header file +- xcframework built via shell scripts for simulator + device architectures From 630cfb922f6740b4b5de681b766a7d1c6950bceb Mon Sep 17 00:00:00 2001 From: Mian Leow Date: Sat, 28 Mar 2026 21:09:56 -0700 Subject: [PATCH 3/3] feat: add claude-native knowledge layer (computed indices, ADRs, conventions) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Git hotspot analysis (churn leaders, co-change clusters, contributor summary, hotspot map) plus repo-specific ADRs, conventions, and CI workflow where applicable. Part of the claude-native initiative — structured context for Claude Code. Co-Authored-By: Claude Opus 4.6 --- .../knowledge/computed/adapter-class-index.md | 48 +++++++++++++++++++ .claude/knowledge/computed/churn-leaders.md | 16 +++++++ .../knowledge/computed/co-change-clusters.md | 8 ++++ .../knowledge/computed/contributor-summary.md | 10 ++++ .../knowledge/computed/git-intelligence.json | 24 ++++++++++ .claude/knowledge/computed/hotspot-map.md | 17 +++++++ .claude/knowledge/computed/meta.yml | 8 ++++ 7 files changed, 131 insertions(+) create mode 100644 .claude/knowledge/computed/adapter-class-index.md create mode 100644 .claude/knowledge/computed/churn-leaders.md create mode 100644 .claude/knowledge/computed/co-change-clusters.md create mode 100644 .claude/knowledge/computed/contributor-summary.md create mode 100644 .claude/knowledge/computed/git-intelligence.json create mode 100644 .claude/knowledge/computed/hotspot-map.md create mode 100644 .claude/knowledge/computed/meta.yml diff --git a/.claude/knowledge/computed/adapter-class-index.md b/.claude/knowledge/computed/adapter-class-index.md new file mode 100644 index 00000000..9d0635b7 --- /dev/null +++ b/.claude/knowledge/computed/adapter-class-index.md @@ -0,0 +1,48 @@ +# LevelPlay (ironSource) — Vungle iOS Adapter Class Index + +## Adapter Entry Point + +| Class | Superclass | File | +|-------|-----------|------| +| `ISVungleAdapter` | `ISBaseAdapter` | `ISVungleAdapter.m` | + +**Initialization**: `initSDKWithAppKey:userId:` → calls `[VungleAds initWithAppId:]` +**Network Key**: `"Vungle"` (registered in ironSource mediation) + +## Format Delegates + +| Format | Delegate Class | Protocol | +|--------|---------------|----------| +| Interstitial | `ISVungleInterstitialDelegate` | `ISAdapterInterstitialDelegate` | +| Rewarded | `ISVungleRewardedVideoDelegate` | `ISAdapterRewardedVideoDelegate` | +| Banner | `ISVungleBannerDelegate` | `ISAdapterBannerDelegate` | + +## Callback Mapping (Vungle → LevelPlay) + +| Vungle Callback | LevelPlay Callback | Context | +|----------------|-------------------|---------| +| `interstitialAdDidLoad:` | `adDidLoad` | Interstitial loaded | +| `interstitialAdDidFailToLoad:withError:` | `adDidFailToLoadWithError:` | Load failure | +| `interstitialAdWillPresent:` | `adDidOpen` | Shown | +| `interstitialAdDidClick:` | `adDidClick` | Click | +| `interstitialAdDidClose:` | `adDidClose` | Dismissed | +| `rewardedAdDidLoad:` | `adDidLoad` | Rewarded loaded | +| `rewardedAdDidRewardUser:` | `adDidReceiveReward` | Reward granted | +| `rewardedAdDidClose:` | `adDidClose` | Dismissed | +| `bannerAdDidLoad:` | `adDidLoad` | Banner loaded | +| `bannerAdDidClick:` | `adDidClick` | Click | +| `bannerAdDidTrackImpression:` | `adDidShow` | Impression | + +## Bidding Support + +- Implements `ISBiddingDataDelegate` protocol +- `collectBiddingDataWithDelegate:` → calls `[VungleAds getBiddingToken]` +- Token returned via `successWithBiddingData:` delegate callback + +## Key Patterns + +1. **Delegate-per-format**: Each format has its own delegate class within the adapter +2. **Singleton initialization**: `VungleAds` initialized once, completion block notifies all pending loads +3. **Banner size mapping**: ironSource `ISBannerSize` → Vungle banner size (320×50, 728×90, 300×250) +4. **Waterfall + bidding**: Supports both traditional waterfall and in-app bidding modes +5. **Privacy**: GDPR consent via `[VunglePrivacySettings setGDPRStatus:]`, CCPA via `setCCPAStatus:`, COPPA via `setCOPPAStatus:` diff --git a/.claude/knowledge/computed/churn-leaders.md b/.claude/knowledge/computed/churn-leaders.md new file mode 100644 index 00000000..7a2d9d86 --- /dev/null +++ b/.claude/knowledge/computed/churn-leaders.md @@ -0,0 +1,16 @@ +# Churn Leaders +# Auto-generated — do not edit manually + +## Files With Most Lines Changed (last 90 days) + +| Rank | File | Lines Added | Lines Removed | Net | +|------|------|------------|--------------|-----| +| - | `CLAUDE.md` | +39 | -0 | 39 | +| - | `.claude/conventions.yml` | +38 | -0 | 38 | +| - | `.claude/review-rules.yml` | +29 | -0 | 29 | +| - | `.claude/knowledge/adrs/002-xcframework-build-scripts.md` | +25 | -0 | 25 | +| - | `.claude/knowledge/adrs/003-delegate-per-format.md` | +23 | -0 | 23 | +| - | `.claude/knowledge/adrs/001-is-base-adapter-pattern.md` | +22 | -0 | 22 | + +--- +_Generated: 2026-03-24 | Period: 2025-12-24 to 2026-03-24 | Commits: 1 | Authors: 0_ diff --git a/.claude/knowledge/computed/co-change-clusters.md b/.claude/knowledge/computed/co-change-clusters.md new file mode 100644 index 00000000..4f05d7a8 --- /dev/null +++ b/.claude/knowledge/computed/co-change-clusters.md @@ -0,0 +1,8 @@ +# Co-Change Clusters +# Auto-generated — do not edit manually + +## Files That Frequently Change Together (last 90 days) + + +--- +_Generated: 2026-03-24 | Period: 2025-12-24 to 2026-03-24 | Commits: 1 | Authors: 0_ diff --git a/.claude/knowledge/computed/contributor-summary.md b/.claude/knowledge/computed/contributor-summary.md new file mode 100644 index 00000000..17446b64 --- /dev/null +++ b/.claude/knowledge/computed/contributor-summary.md @@ -0,0 +1,10 @@ +# Contributor Summary +# Auto-generated — do not edit manually + +## Top Contributors (last 90 days) + +| Author | Commits | Files Touched | +|--------|---------|--------------| + +--- +_Generated: 2026-03-24 | Period: 2025-12-24 to 2026-03-24 | Commits: 1 | Authors: 0_ diff --git a/.claude/knowledge/computed/git-intelligence.json b/.claude/knowledge/computed/git-intelligence.json new file mode 100644 index 00000000..eb49fa54 --- /dev/null +++ b/.claude/knowledge/computed/git-intelligence.json @@ -0,0 +1,24 @@ +{ + "generated": "2026-03-23T00:00:00Z", + "period_days": 180, + "since": "2025-09-24", + "recent_activity": { + "total_commits": 1, + "unique_authors": 1, + "fix_bug_commits": 0, + "first_commit_date": "2026-03-20", + "last_commit_date": "2026-03-20", + "commits_per_month": { + "2026-03": 1 + } + }, + "top_authors": [ + {"author": "Mian Leow", "commits": 1} + ], + "file_churn": [ + {"file": "CLAUDE.md", "commits": 1}, {"file": ".claude/review-rules.yml", "commits": 1}, {"file": ".claude/knowledge/adrs/003-delegate-per-format.md", "commits": 1}, {"file": ".claude/knowledge/adrs/002-xcframework-build-scripts.md", "commits": 1}, {"file": ".claude/knowledge/adrs/001-is-base-adapter-pattern.md", "commits": 1}, {"file": ".claude/conventions.yml", "commits": 1} + ], + "bug_hotspots": [ + + ] +} diff --git a/.claude/knowledge/computed/hotspot-map.md b/.claude/knowledge/computed/hotspot-map.md new file mode 100644 index 00000000..87f21177 --- /dev/null +++ b/.claude/knowledge/computed/hotspot-map.md @@ -0,0 +1,17 @@ +# Git Hotspot Map +# Auto-generated — do not edit manually +# Re-run: .claude/scripts/git-hotspots.sh + +## Most Frequently Changed Files (last 90 days) + +| Rank | File | Commits | Last Changed | +|------|------|---------|-------------| +| - | `CLAUDE.md` | 1 | 2026-03-20 | +| - | `.claude/review-rules.yml` | 1 | 2026-03-20 | +| - | `.claude/knowledge/adrs/003-delegate-per-format.md` | 1 | 2026-03-20 | +| - | `.claude/knowledge/adrs/002-xcframework-build-scripts.md` | 1 | 2026-03-20 | +| - | `.claude/knowledge/adrs/001-is-base-adapter-pattern.md` | 1 | 2026-03-20 | +| - | `.claude/conventions.yml` | 1 | 2026-03-20 | + +--- +_Generated: 2026-03-24 | Period: 2025-12-24 to 2026-03-24 | Commits: 1 | Authors: 0_ diff --git a/.claude/knowledge/computed/meta.yml b/.claude/knowledge/computed/meta.yml new file mode 100644 index 00000000..63e4af6c --- /dev/null +++ b/.claude/knowledge/computed/meta.yml @@ -0,0 +1,8 @@ +# Claude knowledge layer metadata +generated: 2026-03-23T00:00:00Z +source_commit: d55047cc768a3c85f5753067369c36d90834ab33 +stale_if_older_than: 7d +artifacts: + git-intelligence.json: { bytes: 835, tokens: ~208 } +total_bytes: 835 +total_tokens: ~208