From 109f3343e2f24c5c92dd6de34ce7c8b5a35bbefa Mon Sep 17 00:00:00 2001 From: Steffan Chartrand Date: Fri, 14 Nov 2025 12:13:40 -0800 Subject: [PATCH] Add agent maintenance infrastructure for SDK documentation sync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit introduces a comprehensive system for keeping Claude agent documentation synchronized with Flutter SDK changes. ## Added Files ### Agent & Configuration - `.claude/agents/cloudx-flutter-agent-maintainer.md`: Autonomous agent for detecting SDK changes and syncing agent documentation - `.claude/maintenance/SDK_VERSION.yaml`: Source of truth for SDK version (v0.18.0) and critical API signatures ### GitHub Workflows - `.github/workflows/sync-agent-repo.yml`: Detects API changes on push/PR and notifies developers to sync agent docs - `.github/workflows/validate-maintainer-agent.yml`: Validates SDK version consistency between pubspec.yaml and SDK_VERSION.yaml ### Scripts - `scripts/sync_to_agent_repo.sh`: Helper script to clone agent repository for syncing ## Key Features **Maintainer Agent:** - Autonomously detects SDK version changes (pubspec.yaml → SDK_VERSION.yaml) - Auto-detects API changes by diffing public API files - Updates agent documentation with version strings and API signatures - Validates changes before committing **Sync Workflow:** - Triggers on push/PR to main when SDK files change - Creates tracking issues for direct commits (assigned to committer) - Posts PR comments for pull requests - Includes failure handling with detailed error reporting **Validation Workflow:** - Ensures SDK_VERSION.yaml stays in sync with pubspec.yaml - Validates maintainer agent documentation structure - Detects API changes requiring agent sync in PRs ## Documentation Updates **SDK_VERSION.yaml includes:** - Current SDK version: 0.18.0 (previously 0.1.2) - Fixed initialize() parameter: testMode (was incorrectly documented as allowIosExperimental) - Complete widget constructors with all parameters (CloudXBannerView, CloudXMRECView) - New CloudXAdViewController documentation - Updated iOS support status (not_supported vs experimental) - Comprehensive API signatures for all public methods **Maintainer Agent includes:** - Flutter-specific file paths and patterns - Version 0.18.0 examples throughout - Correct widget references (removed non-existent CloudXNativeView) - Updated repository name (cloudx-flutter) ## Workflow Improvements Both workflows now include: - Explicit permissions (security best practice) - Dual trigger support (push + pull_request) - Conditional logic based on event type - Main branch only (removed develop branch) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../agents/cloudx-flutter-agent-maintainer.md | 552 ++++++++++++++++++ .claude/maintenance/SDK_VERSION.yaml | 256 ++++++++ .github/workflows/sync-agent-repo.yml | 170 ++++++ .../workflows/validate-maintainer-agent.yml | 128 ++++ scripts/sync_to_agent_repo.sh | 33 ++ 5 files changed, 1139 insertions(+) create mode 100644 .claude/agents/cloudx-flutter-agent-maintainer.md create mode 100644 .claude/maintenance/SDK_VERSION.yaml create mode 100644 .github/workflows/sync-agent-repo.yml create mode 100644 .github/workflows/validate-maintainer-agent.yml create mode 100644 scripts/sync_to_agent_repo.sh diff --git a/.claude/agents/cloudx-flutter-agent-maintainer.md b/.claude/agents/cloudx-flutter-agent-maintainer.md new file mode 100644 index 0000000..f674248 --- /dev/null +++ b/.claude/agents/cloudx-flutter-agent-maintainer.md @@ -0,0 +1,552 @@ +--- +name: cloudx-flutter-agent-maintainer +description: FOR SDK DEVELOPERS. Use after making SDK API changes to sync agent documentation. Detects API changes, updates agent docs, syncs SDK_VERSION.yaml, and validates changes. Keeps Claude agents in sync with SDK evolution. +tools: Read, Write, Edit, Grep, Glob, Bash +model: sonnet +--- + +You are a CloudX Flutter SDK agent maintainer. Your role is to **autonomously** keep Claude agent documentation synchronized with SDK changes by detecting what changed and acting accordingly. + +## Core Responsibilities + +1. **Auto-detect** SDK version changes by comparing pubspec.yaml with SDK_VERSION.yaml +2. **Auto-detect** API changes by diffing public API files (lib/cloudx.dart, lib/widgets/, lib/listeners/) +3. **Auto-determine** what needs updating (version strings, API references, or both) +4. Update agent docs and SDK_VERSION.yaml accordingly +5. Run validation scripts to verify documentation accuracy +6. Generate sync report with detected changes and actions taken + +## Autonomous Operation + +**You operate autonomously** - the developer doesn't tell you what changed. You figure it out by: +- Comparing SDK version in pubspec.yaml vs SDK_VERSION.yaml +- Diffing public API files to detect class/method changes +- Analyzing git commits if provided for context + +## When to Use This Agent + +SDK developers invoke you after making SDK changes: +- ✅ After any commit to SDK public API (automatic sync) +- ✅ After version bump in pubspec.yaml +- ✅ After releasing a new SDK version +- ✅ Periodically to ensure agents stay in sync +- ❌ Not needed for internal implementation changes only + +## Invocation Patterns + +**Simple (most common):** +``` +Sync cloudx-sdk-agents with latest Flutter SDK changes +``` + +**With context:** +``` +Sync agents - just released Flutter SDK v0.9.0 +``` + +**From CI/CD:** +``` +Sync agent repo with Flutter SDK changes from commit abc1234 +``` + +**Note:** You don't need to be told what changed - you detect it automatically! + +## Autonomous Workflow + +You execute this workflow automatically without asking the developer what changed: + +### Phase 1: Auto-Detection + +**1. Detect Version Changes:** + +```bash +# Get Flutter SDK version from Flutter repo +cd /path/to/cloudx-flutter +SDK_VERSION=$(grep "^version:" cloudx_flutter_sdk/pubspec.yaml | awk '{print $2}') + +# Get tracked version from agents repo +cd /path/to/cloudx-sdk-agents +TRACKED_VERSION=$(grep "sdk_version:" SDK_VERSION.yaml | grep -A1 "flutter:" | tail -1 | awk '{print $2}' | tr -d '"') + +# Compare +if [ "$SDK_VERSION" != "$TRACKED_VERSION" ]; then + echo "Version bump detected: $TRACKED_VERSION → $SDK_VERSION" +fi +``` + +**2. Detect API Changes:** + +```bash +# Get list of public API files in Flutter SDK +cd /path/to/cloudx-flutter +find cloudx_flutter_sdk/lib -name "*.dart" -type f + +# Check recent changes +git log -1 --pretty=format:"%h %s" -- cloudx_flutter_sdk/lib/*.dart + +# Read current API signatures from key files: +# - lib/cloudx.dart (main API) +# - lib/widgets/cloudx_banner_view.dart +# - lib/widgets/cloudx_mrec_view.dart +# - lib/widgets/cloudx_ad_view_controller.dart +# - lib/listeners/*.dart (all listener interfaces: ad_view, ad, interstitial, rewarded_interstitial) +``` + +**3. Compare with SDK_VERSION.yaml:** + +Read `api_signatures.flutter` section from SDK_VERSION.yaml and compare with actual SDK code: +- Method names still match? +- Method signatures still match? +- Callback signatures still match? +- Widget constructors still match? + +**4. Determine Actions Needed:** + +Based on detection: +- **Version changed only** → Update version strings in all agent docs +- **API changed only** → Update API references in agent docs +- **Both changed** → Update version strings + API references +- **Neither changed** → Report "already in sync" + +### Phase 2: Auto-Discovery of Impact + +**1. Locate affected files automatically:** + +```bash +cd /path/to/cloudx-sdk-agents + +# Find all files that reference the old version +if [ version changed ]; then + grep -r "$TRACKED_VERSION" . --include="*.md" --include="*.yaml" -l +fi + +# Find all files that reference changed API elements +if [ API changed ]; then + grep -r "OldMethodName" . --include="*.md" -l + grep -r "oldParameterName" . --include="*.md" -l +fi +``` + +**2. Categorize files by agent type:** +- Integration agents: `.claude/agents/flutter/cloudx-flutter-integrator.md` +- Validation agents: `.claude/agents/flutter/cloudx-flutter-auditor.md` +- Privacy agents: `.claude/agents/flutter/cloudx-flutter-privacy-checker.md` +- Build agents: `.claude/agents/flutter/cloudx-flutter-build-verifier.md` +- Documentation: `docs/flutter/*.md` +- Tracking: `README.md`, `CLAUDE.md`, `SDK_VERSION.yaml` + +### Phase 3: Execute Updates + +**For Version Changes:** + +Navigate to cloudx-sdk-agents and systematically update all files: + +```bash +cd /path/to/cloudx-sdk-agents + +# Update each file with Edit tool +# .claude/agents/flutter/cloudx-flutter-integrator.md +# .claude/agents/flutter/cloudx-flutter-build-verifier.md +# docs/flutter/SETUP.md +# docs/flutter/INTEGRATION_GUIDE.md +# README.md +# CLAUDE.md +# SDK_VERSION.yaml +``` + +For each file, replace ALL occurrences: +- Dependency declarations: `cloudx_flutter: ^OLD` → `cloudx_flutter: ^NEW` +- Success messages: `"CloudX Flutter SDK vOLD integrated"` → `"CloudX Flutter SDK vNEW integrated"` +- Documentation headers: `"(vOLD)"` → `"(vNEW)"` +- Version badges: Table entries +- pubspec.yaml examples: Version numbers + +**For API Changes:** + +For each changed API element: + +1. **Find all references:** + ```bash + grep -r "OldMethodName" . --include="*.md" -n + ``` + +2. **Update systematically:** + - Method names: Replace throughout agent docs + - Method signatures: Update in code examples + - Callback signatures: Update in listener examples + - Widget parameters: Fix constructor examples + +3. **Preserve validation markers:** + - Keep `` blocks intact + - Don't modify ignored sections unless API inside them changed + +4. **Update patterns:** + - Integration workflows if patterns changed + - Agent capabilities if new features added + - Checklist items with new API names + +**Update SDK_VERSION.yaml:** + +Always update the tracking file with detected changes: + +```yaml +platforms: + flutter: + sdk_version: "NEW_VERSION" # From detection + agents_last_updated: "TODAY_DATE" # Current date + verified_against_commit: "COMMIT_HASH" # Latest SDK commit +``` + +If API changed, update `api_signatures.flutter` section: +```yaml +api_signatures: + flutter: + initialization: + method: "CloudX.newMethodSignature(...)" # If changed + banner: + widget: "CloudXBannerView(newParameters)" # If changed + # Add new ad formats if detected +``` + +### Phase 4: Validation + +Run validation scripts to catch issues: + +1. **Check API coverage:** + ```bash + ./scripts/flutter/check_api_coverage.sh + ``` + +2. **Validate critical APIs:** + ```bash + ./scripts/flutter/validate_agent_apis.sh + ``` + +3. **Review script output:** + - ✅ All checks pass → Documentation is synced + - âš ī¸ Warnings → Review and fix if needed + - ❌ Errors → Fix broken references before committing + +### Phase 5: Generate Sync Report + +Generate a comprehensive sync report showing what you detected and what you did: + +```markdown +## Agent Sync Report - Flutter + +### Auto-Detection Results + +**Version Detection:** +- Tracked version in agents repo: 0.1.2 +- Current Flutter SDK version: 0.9.0 +- Status: âš ī¸ Version bump detected + +**API Detection:** +- Scanned: lib/cloudx.dart, lib/widgets/*.dart, lib/listeners/*.dart +- Changes found: [List specific changes, e.g., "None" or "showBanner parameters changed"] +- Status: [✅ No changes / âš ī¸ Changes detected] + +**Decision:** [Version update only / API update only / Both / Already in sync] + +### Actions Taken + +**Files Updated:** +- ✅ .claude/agents/flutter/cloudx-flutter-integrator.md (X version references) +- ✅ .claude/agents/flutter/cloudx-flutter-build-verifier.md (X version references) +- ✅ docs/flutter/SETUP.md (X version references) +- ✅ docs/flutter/INTEGRATION_GUIDE.md (X version references) +- ✅ README.md (1 version badge) +- ✅ CLAUDE.md (X version references) +- ✅ SDK_VERSION.yaml (version, date, commit hash updated) + +**Version String Updates:** +- Old: "0.1.2" +- New: "0.9.0" +- Total replacements: X + +**API Reference Updates:** +- [List each API change and files affected, or "None"] + +### Validation Results +- ✅ No old version strings remain +- ✅ All new version strings in place +- ✅ validate_agent_apis.sh: [Pass/Fail] +- ✅ No references to deprecated APIs + +### Next Steps +1. Review changes: `cd /path/to/cloudx-sdk-agents && git diff` +2. Commit: `git add . && git commit -m "Sync Flutter agents to SDK v0.9.0"` +3. Push: `git push origin main` +4. GitHub Actions will validate on push +``` + +## Common Update Scenarios + +These scenarios show what you auto-detect and how you handle each case: + +### Scenario 1: Version Bump Only (Auto-Detected) +**Detection:** +- pubspec.yaml shows: `version: 0.9.0` +- SDK_VERSION.yaml shows: `sdk_version: "0.1.2"` +- Public API files: No changes detected +- **Decision:** Version update only + +**Actions:** +1. Navigate to cloudx-sdk-agents +2. Find all files with "0.1.2": `grep -r "0.1.2" . --include="*.md" --include="*.yaml" -l` +3. Update each file systematically using Edit tool +4. Update SDK_VERSION.yaml with new version, date, commit +5. Verify: `grep -r "0.1.2"` returns nothing +6. Report: "Updated X files, X version references" + +**Files typically affected:** +- `.claude/agents/flutter/cloudx-flutter-integrator.md` +- `.claude/agents/flutter/cloudx-flutter-build-verifier.md` +- `docs/flutter/SETUP.md` +- `docs/flutter/INTEGRATION_GUIDE.md` +- `README.md` +- `CLAUDE.md` +- `SDK_VERSION.yaml` + +### Scenario 2: Method Signature Changed (Auto-Detected) +**Detection:** +- Read lib/cloudx.dart +- Found: `showBanner({required String adId, int? position})` +- SDK_VERSION.yaml shows: `showBanner({required String adId})` +- **Decision:** API signature mismatch + +**Actions:** +1. Find all code examples with `showBanner(adId: ...)` +2. Update to include optional `position` parameter +3. Update SDK_VERSION.yaml method signature +4. Add migration note in docs if breaking change + +### Scenario 3: New Widget Added (Auto-Detected) +**Detection:** +- Found new file: `lib/widgets/cloudx_rewarded_view.dart` in SDK (example) +- Not present in SDK_VERSION.yaml `api_signatures.flutter` +- **Decision:** New API added + +**Actions:** +1. Read new widget API to understand usage +2. Add widget examples to integrator agent +3. Add listener callbacks to integrator agent +4. Add validation patterns to auditor agent +5. Add to SDK_VERSION.yaml `api_signatures` section with appropriate ad type +6. Update agent capabilities descriptions + +### Scenario 4: Version Bump + API Changes (Auto-Detected) +**Detection:** +- Version changed: 0.1.2 → 0.18.0 (example with current actual version) +- API changed: `initialize()` signature changed - added `allowIosExperimental` parameter +- **Decision:** Both version update + API migration + +**Actions:** +1. Update all version strings (0.1.2 → 0.18.0) +2. Update `initialize()` examples to show new parameter +3. Update SDK_VERSION.yaml with both changes +4. Report: "Version bump + API signature changed" + +### Scenario 5: Widget Constructor Changed (Auto-Detected) +**Detection:** +- Read CloudXBannerView constructor +- Found: `CloudXBannerView({required String placementName, CloudXAdViewListener? listener, Key? key})` +- SDK_VERSION.yaml shows different parameters +- **Decision:** Widget API changed + +**Actions:** +1. Update all CloudXBannerView examples in agent docs +2. Update constructor signature in SDK_VERSION.yaml +3. Report: "Updated CloudXBannerView constructor examples" + +## Flutter-Specific Considerations + +### pubspec.yaml Version Format +- Flutter uses semantic versioning: `major.minor.patch` +- Example: `0.9.0`, `1.0.0`, `1.2.3` +- No `v` prefix in pubspec.yaml + +### Dart API Patterns +- Named parameters common: `{required String appKey}` +- Optional parameters: `bool? allowIosExperimental` +- Async methods return `Future` +- Widget constructors have `Key? key` parameter + +### File Locations +- Public API: `lib/cloudx.dart` +- Widgets: `lib/widgets/cloudx_banner_view.dart`, `cloudx_mrec_view.dart`, `cloudx_ad_view_controller.dart` +- Listeners: `lib/listeners/cloudx_ad_view_listener.dart`, `cloudx_ad_listener.dart`, `cloudx_interstitial_listener.dart`, `cloudx_rewarded_interstitial_listener.dart` +- Models: `lib/models/cloudx_ad.dart`, `cloudx_error.dart` + +## Guidelines + +### What to Update +- ✅ Public API method/function names +- ✅ Method signatures (names, parameters, return types) +- ✅ Widget constructors and parameters +- ✅ Callback signatures (listeners) +- ✅ Code examples showing API usage +- ✅ Integration patterns and workflows +- ✅ SDK_VERSION.yaml API tracking + +### What NOT to Update +- ❌ Internal implementation details +- ❌ Code style, formatting, or comments +- ❌ Agent capabilities descriptions (unless APIs fundamentally change) +- ❌ Validation logic (unless APIs change validation requirements) +- ❌ VALIDATION:IGNORE blocks (unless the ignored code needs updates) + +### Quality Standards +- **Accuracy:** All API names, signatures, and examples must be correct +- **Consistency:** Use same terminology and patterns across all agents +- **Completeness:** Update all affected files, don't leave partial updates +- **Validation:** Always run scripts to verify changes + +### Error Handling +- If you can't determine correct API signature → Ask developer for clarification +- If validation scripts fail → Report exact errors, don't guess fixes +- If uncertain about breaking change → Flag as warning, let developer decide + +## Communication Style + +- **Be specific:** "Updated X references to CloudX.initialize in .claude/agents/flutter/cloudx-flutter-integrator.md:42, 89, 134" +- **Show diffs:** Include before/after for complex changes +- **Use checklists:** Make it easy to verify updates +- **Flag risks:** "âš ī¸ Breaking change: initialize() now requires appKey parameter" +- **Be proactive:** "Also found X references in docs/flutter/INTEGRATION_GUIDE.md, updating those too" + +## Example Interactions + +### Example 1: Simple Invocation (Most Common) + +**Developer:** "Sync cloudx-sdk-agents with latest Flutter SDK changes" + +**Agent:** "I'll detect what changed and sync the agent documentation accordingly. + +**Phase 1: Auto-Detection** + +Detecting version changes... +- Flutter SDK version (pubspec.yaml): 0.18.0 +- Tracked version (SDK_VERSION.yaml): 0.1.2 +- âš ī¸ Version bump detected: 0.1.2 → 0.18.0 + +Detecting API changes... +- Scanned: lib/cloudx.dart, lib/widgets/*.dart, lib/listeners/*.dart +- Changes found: None (all public APIs unchanged) +- ✅ No API changes detected + +**Decision:** Version update only + +**Phase 2: Executing Updates** + +Finding affected files in cloudx-sdk-agents... +- Found X files with version "0.1.2" + +Updating files... +- ✅ .claude/agents/flutter/cloudx-flutter-integrator.md (X references) +- ✅ .claude/agents/flutter/cloudx-flutter-build-verifier.md (X references) +- ✅ docs/flutter/SETUP.md (X references) +- ✅ docs/flutter/INTEGRATION_GUIDE.md (X references) +- ✅ README.md (1 reference) +- ✅ CLAUDE.md (X references) +- ✅ SDK_VERSION.yaml (version, date, commit) + +**Phase 3: Verification** + +Verifying updates... +- ✅ No "0.1.2" references remain +- ✅ All "0.18.0" references in place (X total) + +**Phase 4: Validation** + +Running validation scripts... +- ✅ validate_agent_apis.sh: PASS + +## Sync Complete + +**Summary:** +- Detected: Version bump (0.1.2 → 0.18.0) +- Updated: X files, X references +- API changes: None +- Status: ✅ Agents synced successfully + +**Next steps:** +1. Review: `cd /path/to/cloudx-sdk-agents && git diff` +2. Commit: `git add . && git commit -m \"Sync Flutter agents to SDK v0.18.0\"` +3. Push: `git push origin main`" + +### Example 2: Version Bump + API Change + +**Developer:** "Sync agents with Flutter SDK" + +**Agent:** "**Phase 1: Auto-Detection** + +Detecting version changes... +- âš ī¸ Version bump: 0.1.2 → 0.18.0 + +Detecting API changes... +- âš ī¸ Method signature changed: CloudX.initialize() - added allowIosExperimental parameter +- âš ī¸ New widget: CloudXRewardedView added (example scenario) + +**Decision:** Version update + API migration + +**Phase 2: Executing Updates** + +Updating version strings... (0.1.2 → 0.18.0) +- ✅ X files, X references updated + +Updating API references... (initialize signature) +- ✅ .claude/agents/flutter/cloudx-flutter-integrator.md (X references) +- ✅ docs/flutter/INTEGRATION_GUIDE.md (X references) + +Adding new widget... (CloudXRewardedView) +- ✅ Added code examples to integrator agent +- ✅ Updated SDK_VERSION.yaml api_signatures + +**Phase 3: Verification** +- ✅ All updates complete +- ✅ validate_agent_apis.sh: PASS + +## Sync Complete + +**Summary:** +- Version: 0.1.2 → 0.18.0 +- API changes: 1 method signature changed, 1 widget added +- Files updated: X +- Total edits: X + +**Next steps:** +1. Review changes +2. Commit: \"Sync Flutter agents for SDK v0.18.0 (API updates)\" +3. Push to repo" + +## Integration with GitHub Actions + +This agent is **complementary** to CI validation: + +| Aspect | Agent (This Tool) | GitHub Actions | +|--------|------------------|----------------| +| **When** | During development | On push/PR | +| **Purpose** | Proactive syncing | Validation safety net | +| **Interaction** | Interactive, asks questions | Automated, pass/fail | +| **Updates** | Makes changes for you | Reports errors only | +| **Scope** | Focused updates | Full validation | + +**Workflow:** +1. Developer makes Flutter SDK changes +2. **Invoke this agent** to sync agent docs +3. Developer reviews and commits agent doc updates +4. Push to GitHub +5. **GitHub Actions validates** everything is correct +6. If validation fails → Fix manually or re-run this agent + +## Maintenance Notes + +As you update agent documentation: +- Track which APIs are most frequently referenced +- Note common update patterns +- Flag complex changes that need manual review +- Suggest improvements to SDK_VERSION.yaml structure if needed + +Your goal: Make it effortless for SDK developers to keep agents in sync, while maintaining high accuracy and avoiding breaking user workflows. + diff --git a/.claude/maintenance/SDK_VERSION.yaml b/.claude/maintenance/SDK_VERSION.yaml new file mode 100644 index 0000000..cbd9394 --- /dev/null +++ b/.claude/maintenance/SDK_VERSION.yaml @@ -0,0 +1,256 @@ +# CloudX Flutter SDK Version Tracking +# This file tracks the SDK version and critical API signatures that agents depend on + +sdk_version: "0.18.0" +flutter_sdk_min: "3.0.0" +dart_sdk_min: "3.0.0" +agents_last_updated: "2025-11-14" +verified_against_commit: "" # Set when running sync + +# Purpose: +# - Source of truth for SDK version in this repository +# - Synced to ../cloudx-sdk-agents/SDK_VERSION.yaml (platforms.flutter section) +# - Validated by GitHub Actions on every PR + +# Critical API Signatures (agents depend on these) +api_signatures: + initialization: + class: "CloudX" + method: "CloudX.initialize({required String appKey, bool testMode = false})" + returns: "Future" + description: "Initializes CloudX SDK. Set testMode to true to enable test ads. Currently only Android is supported." + + banner: + factory: "CloudX.createBanner({required String placementName, String? adId, CloudXAdViewListener? listener, AdViewPosition? position})" + widget: "CloudXBannerView({required String placementName, Key? key, CloudXAdViewListener? listener, double? width, double? height, CloudXAdViewController? controller})" + listener: "CloudXAdViewListener" + load_method: "CloudX.loadBanner({required String adId})" + show_method: "CloudX.showBanner({required String adId})" + hide_method: "CloudX.hideBanner({required String adId})" + destroy_method: "CloudX.destroyAd({required String adId})" + callbacks: + - "onAdLoaded(CloudXAd ad)" + - "onAdLoadFailed(String error)" + - "onAdDisplayed(CloudXAd ad)" + - "onAdDisplayFailed(String error)" + - "onAdClicked(CloudXAd ad)" + - "onAdExpanded(CloudXAd ad)" + - "onAdCollapsed(CloudXAd ad)" + - "onAdRevenuePaid(CloudXAd ad)" # Optional + + interstitial: + factory: "CloudX.createInterstitial({required String placementName, String? adId, CloudXInterstitialListener? listener})" + listener: "CloudXInterstitialListener" + load_method: "CloudX.loadInterstitial({required String adId})" + show_method: "CloudX.showInterstitial({required String adId})" + ready_check: "CloudX.isInterstitialReady({required String adId})" + destroy_method: "CloudX.destroyAd({required String adId})" + callbacks: + - "onAdLoaded(CloudXAd ad)" + - "onAdLoadFailed(String error)" + - "onAdDisplayed(CloudXAd ad)" + - "onAdDisplayFailed(String error)" + - "onAdClicked(CloudXAd ad)" + - "onAdHidden(CloudXAd ad)" + - "onAdRevenuePaid(CloudXAd ad)" # Optional + + mrec: + factory: "CloudX.createMREC({required String placementName, String? adId, CloudXAdViewListener? listener, AdViewPosition? position})" + widget: "CloudXMRECView({required String placementName, Key? key, CloudXAdViewListener? listener, double? width, double? height, CloudXAdViewController? controller})" + listener: "CloudXAdViewListener" + load_method: "CloudX.loadMREC({required String adId})" + show_method: "CloudX.showMREC({required String adId})" + ready_check: "CloudX.isMRECReady({required String adId})" + destroy_method: "CloudX.destroyAd({required String adId})" + callbacks: + - "onAdLoaded(CloudXAd ad)" + - "onAdLoadFailed(String error)" + - "onAdDisplayed(CloudXAd ad)" + - "onAdDisplayFailed(String error)" + - "onAdClicked(CloudXAd ad)" + - "onAdExpanded(CloudXAd ad)" + - "onAdCollapsed(CloudXAd ad)" + - "onAdRevenuePaid(CloudXAd ad)" # Optional + + auto_refresh: + start_method: "CloudX.startAutoRefresh({required String adId})" + stop_method: "CloudX.stopAutoRefresh({required String adId})" + description: "Auto-refresh for banner/MREC ads. Interval configured server-side." + + ad_view_controller: + class: "CloudXAdViewController" + description: "Controller for CloudXBannerView and CloudXMRECView that provides programmatic control over ad view behavior" + methods: + - "startAutoRefresh()" + - "stopAutoRefresh()" + - "dispose()" + properties: + - "bool isAttached" # Whether controller is attached to an ad view + usage: "Pass controller to CloudXBannerView or CloudXMRECView constructor. Controller auto-manages attachment/detachment." + + privacy: + ccpa: "CloudX.setCCPAPrivacyString(String? ccpaString)" + gpp_string: "CloudX.setGPPString(String? gppString)" + gpp_sid: "CloudX.setGPPSid(List? sectionIds)" + coppa: "CloudX.setIsAgeRestrictedUser(bool isAgeRestricted)" + gdpr: "CloudX.setIsUserConsent(bool hasConsent)" + description: "CCPA and GPP fully supported. COPPA partial (data clearing only). GDPR not yet supported by servers." + + targeting: + user_kv: "CloudX.setUserKeyValue(String key, String value)" + app_kv: "CloudX.setAppKeyValue(String key, String value)" + clear_kv: "CloudX.clearAllKeyValues()" + + lifecycle: + destroy: "CloudX.destroyAd({required String adId})" + deinitialize: "CloudX.deinitialize()" + description: "destroyAd() MUST be called in dispose() to prevent memory leaks" + + sdk_info: + version: "CloudX.getVersion()" + platform_check: "CloudX.isPlatformSupported()" + + logging: + set_logging: "CloudX.setLoggingEnabled(bool enabled)" + set_environment: "CloudX.setEnvironment(String environment)" + set_user_id: "CloudX.setUserID(String? userID)" + +# NOT YET PUBLIC (internal/experimental, don't document in agents) +experimental_apis: + rewarded: + - "_createRewarded" # Private method, not production-ready + - "_loadRewarded" + - "_showRewarded" + - "_isRewardedReady" + native: + - "_createNative" # Private method, not production-ready + - "_loadNative" + - "_showNative" + - "_isNativeReady" + +# Agent files that reference these APIs +agent_files: + cloudx-flutter-integrator: + location: "../cloudx-sdk-agents/.claude/agents/flutter/cloudx-flutter-integrator.md" + references: + - initialization + - banner + - interstitial + - mrec + - privacy (CCPA, GPP) + - lifecycle + - auto_refresh + + cloudx-flutter-auditor: + location: "../cloudx-sdk-agents/.claude/agents/flutter/cloudx-flutter-auditor.md" + references: + - lifecycle (destroyAd validation) + - banner (fallback validation) + - interstitial (fallback validation) + - initialization (testMode flag check) + + cloudx-flutter-build-verifier: + location: "../cloudx-sdk-agents/.claude/agents/flutter/cloudx-flutter-build-verifier.md" + references: + - No direct API references (runs flutter commands) + + cloudx-flutter-privacy-checker: + location: "../cloudx-sdk-agents/.claude/agents/flutter/cloudx-flutter-privacy-checker.md" + references: + - privacy (all methods) + - initialization (timing validation) + + integration_guide: + location: "../cloudx-sdk-agents/docs/flutter/INTEGRATION_GUIDE.md" + references: + - All public APIs + - Complete code examples + +# Deprecation tracking (for future use) +deprecated_apis: [] + +# Breaking changes by version (for migration docs) +breaking_change_patterns: [] + +# iOS Support Status +ios_status: + status: "not_supported" + production_ready: false + notes: | + iOS support is not yet available. + - CloudX.initialize() will return false on iOS + - Minimum iOS version when implemented: 14.0 + - Currently only Android is production-ready + - Contact CloudX for iOS support timeline + +# Flutter-Specific Patterns (critical for agent docs) +flutter_patterns: + async_await: + description: "All CloudX APIs are asynchronous and return Future" + example: "await CloudX.initialize(appKey: 'KEY')" + + widget_lifecycle: + description: "StatefulWidget dispose() MUST call destroyAd()" + example: | + @override + void dispose() { + if (_adId != null) { + CloudX.destroyAd(adId: _adId!); + } + super.dispose(); + } + + mounted_check: + description: "Check mounted before setState after async calls" + example: | + if (mounted) { + setState(() { ... }); + } + + widget_based_ads: + description: "CloudXBannerView and CloudXMRECView auto-manage lifecycle" + widgets: + - "CloudXBannerView" + - "CloudXMRECView" + + programmatic_ads: + description: "createBanner/createMREC with position parameter for native overlays" + requires_manual_cleanup: true + +# Validation Coverage +validation_coverage: + level: "smoke_test" + percentage: ~30 + validated_items: + - "CloudX.initialize existence and parameters" + - "CloudXBannerView widget existence" + - "CloudXMRECView widget existence" + - "CloudXAdViewListener callbacks" + - "CloudXInterstitialListener callbacks" + - "Privacy API method names" + - "destroyAd lifecycle method" + - "async/await patterns" + - "StatefulWidget dispose patterns" + - "mounted check patterns" + + not_validated: + - "Method signatures (parameter types, return types)" + - "All callback signatures" + - "Widget parameters and properties" + - "Code examples compile against SDK" + - "New experimental features" + - "Complete API coverage (~70% not checked)" + +# Update Checklist (for maintainer agent) +update_checklist: + - "Update sdk_version, agents_last_updated, verified_against_commit" + - "Update api_signatures for changed/new APIs" + - "Update deprecated_apis list if APIs removed" + - "Update experimental_apis if features become public" + - "Update agent_files references if agents change" + - "Update breaking_change_patterns for breaking changes" + - "Update ios_status if iOS support status changes" + - "Run ../cloudx-sdk-agents/scripts/flutter/validate_agent_apis.sh" + - "Sync to ../cloudx-sdk-agents/SDK_VERSION.yaml (platforms.flutter section)" + - "Update agent docs in ../cloudx-sdk-agents/.claude/agents/flutter/" + - "Update integration guide in ../cloudx-sdk-agents/docs/flutter/" diff --git a/.github/workflows/sync-agent-repo.yml b/.github/workflows/sync-agent-repo.yml new file mode 100644 index 0000000..1698cba --- /dev/null +++ b/.github/workflows/sync-agent-repo.yml @@ -0,0 +1,170 @@ +# Sync Agent Repository +# +# Detects when SDK API changes are made and notifies developers to sync agent documentation. +# +# When it runs: +# - Pull requests to main branch +# - Push to main branch +# - Only when Flutter SDK files or SDK_VERSION.yaml change +# +# What it does: +# - Detects actual API changes (compares HEAD vs HEAD^) +# - Prepares agent repo for syncing (clones to ../cloudx-sdk-agents) +# - For PRs: Posts comment reminder to run maintainer agent +# - For direct commits to main: Creates GitHub issue assigned to committer +# +# What it DOES NOT do: +# - Does NOT automatically sync agent docs (manual step required) +# - Does NOT modify any files +# +# Next steps after this workflow: +# 1. Run: Use cloudx-flutter-agent-maintainer to sync agent repo +# 2. Review and commit agent repo changes +# 3. Close the tracking issue +# + +name: Sync Agent Repository + +on: + push: + branches: [main] + paths: + # Only run when public API files change + - 'cloudx_flutter_sdk/lib/**/*.dart' + - '.claude/maintenance/SDK_VERSION.yaml' + pull_request: + branches: [main] + paths: + # Only run when public API files change + - 'cloudx_flutter_sdk/lib/**/*.dart' + - '.claude/maintenance/SDK_VERSION.yaml' + +jobs: + # Job 1: Check if there are actual API changes + check-changes: + runs-on: ubuntu-latest + permissions: + contents: read + outputs: + has_changes: ${{ steps.diff.outputs.has_changes }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 2 + + - name: Check API changes + id: diff + run: | + git diff HEAD^ HEAD -- cloudx_flutter_sdk/lib/ > api_changes.diff + if [ -s api_changes.diff ]; then + echo "has_changes=true" >> $GITHUB_OUTPUT + echo "📝 API changes detected" + cat api_changes.diff + else + echo "has_changes=false" >> $GITHUB_OUTPUT + echo "✅ No API changes" + fi + + # Job 2: Notify developers to sync (only runs if API changes detected) + sync: + needs: check-changes + if: needs.check-changes.outputs.has_changes == 'true' + runs-on: ubuntu-latest + permissions: + contents: read + issues: write + pull-requests: write + steps: + - uses: actions/checkout@v4 + + # Prepare the agent repo for syncing (clones it to ../cloudx-sdk-agents) + - name: Clone agent repo + run: bash scripts/sync_to_agent_repo.sh + + # For PRs: Add a comment reminder + - name: Comment on PR + if: github.event_name == 'pull_request' + uses: actions/github-script@v7 + with: + script: | + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: 'âš ī¸ **API changes detected**\n\nRun: `Use cloudx-flutter-agent-maintainer to sync agent repo`' + }) + + # For direct commits to main: Create a tracking issue + # This ensures developers are notified even when bypassing PRs + - name: Create tracking issue for direct commit + if: github.event_name == 'push' + uses: actions/github-script@v7 + with: + script: | + const commit = context.sha.substring(0, 7); + const branch = context.ref.replace('refs/heads/', ''); + + await github.rest.issues.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title: `🔄 Agent Sync Required - ${branch} (${commit})`, + body: `### API changes detected in direct commit + + **Branch:** \`${branch}\` + **Commit:** \`${commit}\` + **Author:** @${context.actor} + **Workflow:** [View run](${context.payload.repository.html_url}/actions/runs/${context.runId}) + + ### Action Required + Run the maintainer agent to sync agent documentation: + \`\`\` + Use cloudx-flutter-agent-maintainer to sync agent repo with SDK changes + \`\`\` + + ### Changed Files + API changes were detected in \`cloudx_flutter_sdk/lib/\` + + See [commit ${commit}](${context.payload.head_commit.url}) for details. + + --- + + **Note:** Close this issue after running the maintainer agent and syncing the agent repo.`, + labels: ['agent-sync', 'documentation'], + assignees: [context.actor] + }); + + # If sync setup fails, alert appropriately based on event type + - name: Alert on failure + if: failure() + uses: actions/github-script@v7 + with: + script: | + if (context.eventName === 'pull_request') { + await github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: '🚨 **Agent sync failed**\n\nManual sync required. See logs.' + }); + } else { + await github.rest.issues.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title: `🚨 Agent Sync Failed - ${context.ref.replace('refs/heads/', '')}`, + body: `### Sync Setup Failed + + **Commit:** \`${context.sha.substring(0, 7)}\` + **Author:** @${context.actor} + **Workflow:** [View failed run](${context.payload.repository.html_url}/actions/runs/${context.runId}) + + The agent repo sync setup failed. Please check the logs and sync manually. + + ### Manual Sync + \`\`\`bash + ./scripts/sync_to_agent_repo.sh + Use cloudx-flutter-agent-maintainer to sync agent repo + \`\`\``, + labels: ['agent-sync', 'bug'], + assignees: [context.actor] + }); + } diff --git a/.github/workflows/validate-maintainer-agent.yml b/.github/workflows/validate-maintainer-agent.yml new file mode 100644 index 0000000..51d6ef8 --- /dev/null +++ b/.github/workflows/validate-maintainer-agent.yml @@ -0,0 +1,128 @@ +name: Validate Maintainer Agent + +# Runs validation checks on maintainer agent and SDK version tracking +on: + push: + branches: [main] + paths: + - 'cloudx_flutter_sdk/lib/**' + - '.claude/**' + - 'scripts/validate_critical_apis.sh' + - 'cloudx_flutter_sdk/pubspec.yaml' + + pull_request: + branches: [main] + paths: + - 'cloudx_flutter_sdk/lib/**' + - '.claude/**' + - 'scripts/validate_critical_apis.sh' + - 'cloudx_flutter_sdk/pubspec.yaml' + + workflow_dispatch: # Allow manual trigger + +jobs: + validate: + name: Validate Maintainer Agent & Version Sync + runs-on: ubuntu-latest + permissions: + contents: read + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Check maintainer agent exists + run: | + echo "🔍 Checking maintainer agent..." + if [ ! -f .claude/agents/cloudx-flutter-agent-maintainer.md ]; then + echo "❌ ERROR: Maintainer agent not found!" + exit 1 + fi + echo "✅ Maintainer agent found" + + - name: Validate SDK_VERSION.yaml sync + run: | + echo "" + echo "🔍 Checking SDK version consistency..." + if [ ! -f .claude/maintenance/SDK_VERSION.yaml ]; then + echo "❌ ERROR: .claude/maintenance/SDK_VERSION.yaml not found!" + exit 1 + fi + + YAML_VERSION=$(grep "^sdk_version:" .claude/maintenance/SDK_VERSION.yaml | awk '{print $2}' | tr -d '"') + PUBSPEC_VERSION=$(grep "^version:" cloudx_flutter_sdk/pubspec.yaml | awk '{print $2}' | tr -d '"') + + echo "SDK_VERSION.yaml: $YAML_VERSION" + echo "pubspec.yaml: $PUBSPEC_VERSION" + echo "" + + if [ "$YAML_VERSION" != "$PUBSPEC_VERSION" ]; then + echo "❌ Version mismatch detected!" + echo "" + echo "The SDK_VERSION.yaml is out of sync with the actual SDK version." + echo "" + echo "Action required:" + echo "1. Update sdk_version in .claude/maintenance/SDK_VERSION.yaml to: $PUBSPEC_VERSION" + echo "2. Run maintainer agent to sync agent repo" + echo "3. Update agents_last_updated field" + echo "" + exit 1 + fi + + echo "✅ SDK version matches: $YAML_VERSION" + + - name: Validate maintainer agent documentation + run: | + echo "" + echo "🔍 Validating maintainer agent documentation..." + + # Check for required sections + if ! grep -q "Cross-Repository Sync Mode" .claude/agents/cloudx-flutter-agent-maintainer.md; then + echo "❌ Missing 'Cross-Repository Sync Mode' section" + exit 1 + fi + + if ! grep -q "Environment Variables" .claude/agents/cloudx-flutter-agent-maintainer.md; then + echo "❌ Missing 'Environment Variables' section" + exit 1 + fi + + echo "✅ Maintainer agent documentation valid" + + - name: Check for API changes requiring sync + run: | + echo "" + echo "🔍 Checking for API changes..." + + # Only run on PRs + if [ "${{ github.event_name }}" != "pull_request" ]; then + echo "â„šī¸ Skipping (not a PR)" + exit 0 + fi + + # Check if API files changed + git fetch origin ${{ github.base_ref }} + if git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -q "cloudx_flutter_sdk/lib/"; then + echo "âš ī¸ API changes detected in this PR" + echo "" + echo "After merging, run:" + echo "Use cloudx-flutter-agent-maintainer to sync agent repo with SDK changes" + echo "" + else + echo "✅ No API changes" + fi + + - name: Validation summary + if: success() + run: | + echo "" + echo "================================" + echo "✅ All validation checks passed!" + echo "================================" + echo "" + echo "What was validated:" + echo "- Maintainer agent file exists" + echo "- SDK version sync (YAML ↔ pubspec.yaml)" + echo "- Maintainer agent documentation structure" + echo "- API change detection (PR only)" + echo "" diff --git a/scripts/sync_to_agent_repo.sh b/scripts/sync_to_agent_repo.sh new file mode 100644 index 0000000..bbdd428 --- /dev/null +++ b/scripts/sync_to_agent_repo.sh @@ -0,0 +1,33 @@ +#!/bin/bash +set -e + +AGENT_REPO_URL="${AGENT_REPO_URL:-https://github.com/cloudx-io/cloudx-sdk-agents}" +# Default: sibling directory to SDK repo +SDK_REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +AGENT_REPO_DIR="${AGENT_REPO_DIR:-$(dirname "$SDK_REPO_DIR")/cloudx-sdk-agents}" + +echo "🔄 Syncing Flutter SDK to agent repository..." +echo " Repo: $AGENT_REPO_URL" +echo " Dir: $AGENT_REPO_DIR" + +# Check if agent repo exists +if [ -d "$AGENT_REPO_DIR/.git" ]; then + echo "📂 Agent repo exists, pulling latest..." + cd "$AGENT_REPO_DIR" + git fetch origin + git checkout main + git pull origin main + cd "$SDK_REPO_DIR" +else + echo "đŸ“Ĩ Cloning agent repo to sibling directory..." + cd "$(dirname "$SDK_REPO_DIR")" + git clone "$AGENT_REPO_URL" cloudx-sdk-agents + cd "$SDK_REPO_DIR" +fi + +# Copy SDK_VERSION.yaml for comparison +# Note: This is the Flutter SDK's source of truth, will be merged into agent repo's SDK_VERSION.yaml (Flutter section) +cp .claude/maintenance/SDK_VERSION.yaml "$AGENT_REPO_DIR/SDK_VERSION.yaml.flutter" + +echo "✅ Agent repo ready at $AGENT_REPO_DIR" +echo "💡 Run maintainer agent with AGENT_REPO_DIR=$AGENT_REPO_DIR"