diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..37028d3 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,139 @@ +# MotorSignal — Agent Development Rules + +## Project Identity + +MotorSignal is a Flutter motorcycle telemetry and ride-analysis application. + +Before modifying code, agents MUST inspect the relevant existing architecture and +tests and understand the current implementation. + +## Required Development Workflow + +Before making changes: + +1. Inspect the relevant source files. +2. Identify existing services, providers, models, repositories, and tests. +3. Do not duplicate existing functionality. +4. Make the smallest safe change necessary. +5. Preserve existing public interfaces unless the task explicitly requires change. +6. Add or update tests for behavioral changes. +7. Run static analysis. +8. Run the relevant test suite. +9. Run the complete test suite before declaring the task complete. +10. Report exactly what changed and what verification passed. + +## Telemetry Freeze Boundary + +The following subsystem is FROZEN unless the task explicitly requires +modification and the user approves the architectural change: + +- TelemetryService +- SensorFusionService +- RideStateMachine + +### TelemetryService + +Authoritative telemetry acquisition runs at 20 Hz / 50 ms. + +Do not: +- change acquisition cadence +- introduce competing telemetry clocks +- duplicate sensor acquisition +- bypass the authoritative telemetry pipeline +- introduce UI-driven polling of sensors + +All consumers must use the existing telemetry architecture. + +### SensorFusionService + +Sensor fusion is authoritative for derived orientation/lean data. + +Do not introduce an independent lean-angle calculation without explicit +architectural justification and regression tests. + +### RideStateMachine + +Preserve existing movement/crash/recovery semantics. + +The 3.0 MPH moving gate and kickstand isolation behavior are architectural +contracts unless explicitly changed by the user. + +## Database Freeze Boundary + +AppDatabase is currently Schema 5. + +Do not modify database schema, migrations, event semantics, or persistence +behavior casually. + +Any schema change MUST include: + +- migration +- migration tests +- backward compatibility consideration +- verification against existing ride datasets + +Never delete or rewrite historical ride data during feature development. + +## Forensic / Export Freeze Boundary + +FieldTestExportService is authoritative for forensic exports. + +Preserve: + +- CSV schema +- JSON session schema 1 +- GPX export +- timestamp semantics +- event ordering +- sub-second telemetry fidelity + +Feature/UI work must not silently alter exported historical data. + +## State Management + +Follow the project's existing Riverpod architecture. + +Do not introduce another state-management framework. + +Prefer existing providers/services over creating parallel state containers. + +## UI Development + +UI features must consume existing domain/application services. + +Do not place telemetry acquisition, persistence, sensor fusion, or business +logic directly inside widgets. + +Support both portrait and landscape layouts where applicable. + +## Testing + +Every behavioral change requires appropriate automated coverage. + +Before completion: + + dart analyze lib test + flutter test + +A task is NOT considered complete if tests fail, analysis reports new issues, +or existing regression datasets change unexpectedly. + +## Git Safety + +Never reset, force-push, rebase, delete branches, delete tags, or rewrite +history unless explicitly requested. + +Create a checkpoint commit before significant architectural changes. + +Do not modify unrelated files. + +## Agent Behavior + +Investigate before modifying. + +Prefer surgical patches over broad rewrites. + +Do not "fix" unrelated problems discovered during a task. + +If an architectural conflict is discovered, stop and report it rather than +silently changing a frozen subsystem. diff --git a/MOTORSIGNAL_AI_ENVIRONMENT_AUDIT.md b/MOTORSIGNAL_AI_ENVIRONMENT_AUDIT.md new file mode 100644 index 0000000..275b788 --- /dev/null +++ b/MOTORSIGNAL_AI_ENVIRONMENT_AUDIT.md @@ -0,0 +1,134 @@ +# MotorSignal AI Development Environment Audit Report + +**Audit Date:** August 30, 2026 +**Application:** MotorSignal (Motorcycle Telemetry & Performance Dashboard) +**Repository:** `https://github.com/bponders12-cell/flutter-app.git` +**Current Version:** `1.0.2+102` (Git commit: `305c215`, Tag: `v1.0.2`) +**Audit Scope:** Read-only system inspection of toolchains, AI agent configurations, MCP servers, instruction files, testing pipelines, and telemetry freeze boundaries. + +--- + +## 1. Toolchain & Runtime Environment + +| Component | Detected Version | Location / Path | Status | +| :--- | :--- | :--- | :--- | +| **Flutter SDK** | `3.44.6` (Channel `stable`) | `C:\Users\Bill\flutter` | ✅ Operational | +| **Dart SDK** | `3.12.2` (stable, `windows_x64`) | `C:\Users\Bill\flutter\bin\cache\dart-sdk` | ✅ Operational | +| **Java / JDK** | `26.0.1+8-34` (64-Bit Server VM) | `C:\Program Files\Java\jdk-26` | ✅ Operational | +| **Android SDK** | `37.0.0` (API 37) | `C:\Users\Bill\AppData\Local\Android\sdk` | ⚠️ Missing cmdline-tools | +| **Gradle Distribution** | `9.1.0-all` | `android/gradle/wrapper/gradle-wrapper.properties` | ✅ Operational | +| **Android Gradle Plugin** | `9.0.1` | `android/settings.gradle.kts` | ✅ Operational | +| **Kotlin Android Plugin** | `2.3.20` (Target: JVM 17) | `android/settings.gradle.kts` | ✅ Operational | +| **Host OS** | Windows 11 Pro (`26H1`, Build `28120.2760`) | Microsoft Windows x64 | ✅ Operational | + +--- + +## 2. Status Categorization + +### ✅ PASS + +1. **Source Code Cleanliness & Static Analysis:** + - `dart analyze lib test`: **0 errors, 0 warnings, 0 lints**. Full repository passes strict static analysis. +2. **Automated Test Suite Integrity:** + - `flutter test`: **165 / 165 tests passing (100% success rate)** across all 28 test suites, including regression replay of physical field tests (Ride #4, #7, #8, #10, #11, #12, #13). +3. **Telemetry & Sensor Fusion Baseline Freeze:** + - 20 Hz authoritative sampling timer (`50 ms` period) is intact and active. + - Adaptive Dynamic Complementary Filter and sensor fusion math remain 100% frozen. + - 3.0 MPH moving gate, kickstand isolation, and personal record gating remain strictly enforced. + - SQLite batch queue persistence, forensic event logging, and crash-recovery state machine are preserved. +4. **Git Repository Baseline:** + - Active branch: `master` on commit `305c215`. + - Release tags: `v1.0.1` and `v1.0.2` established. + - Remote `origin`: `https://github.com/bponders12-cell/flutter-app.git`. +5. **Context7 Documentation MCP:** + - Active and functioning via `resolve-library-id` and `query-docs`. +6. **Sequential Thinking MCP:** + - Active and functioning via `sequentialthinking`. +7. **Release Binary Generation:** + - Production release APK builds cleanly (`build/app/outputs/flutter-apk/MotorSignal-v1.0.2-build102-release.apk`, 64.2 MB). + +--- + +### ⚠️ WARNING + +1. **Android SDK Command-Line Tools & Licenses:** + - `flutter doctor` notes `cmdline-tools component is missing` and `Android license status unknown`. + - While APK builds succeed using the Gradle wrapper directly, running `flutter doctor --android-licenses` or native CLI profiling requires `cmdline-tools`. +2. **No Physical/Emulated Android Device Currently Attached:** + - `adb devices` shows the daemon is running (`tcp:5037`), but 0 devices/emulators are currently connected. + - Local execution is currently restricted to Windows Desktop (`windows-x64`) and Microsoft Edge (`web-javascript`). +3. **Missing Chrome Executable Path:** + - `CHROME_EXECUTABLE` is not explicitly set in the system environment; `flutter doctor` cannot locate `chrome.exe` at the default path (Edge is used instead). +4. **Visual Studio C++ Desktop Workload Incomplete:** + - Visual Studio 2022 Community is installed, but `MSVC v142` and `CMake tools for Windows` components are not fully installed for native Windows C++ desktop compilation (does not impact Android APK builds). + +--- + +### 🔍 MISSING + +1. **Workspace Agent Instruction Files:** + - No project-level `AGENTS.md`, `GEMINI.md`, `CLAUDE.md`, or `.cursorrules` exist in the workspace root (`c:\Users\Bill\Desktop\flutter-app`). + - Only the global rule `C:\Users\Bill\.gemini\GEMINI.md` (Context7 routing) and built-in Antigravity instructions are active. +2. **Firebase Project Configuration in Flutter App:** + - No `firebase.json`, `android/app/google-services.json`, `ios/Runner/GoogleService-Info.plist`, or `lib/firebase_options.dart` exist. + - No Firebase dependencies (`firebase_core`, `firebase_auth`, `cloud_firestore`) are installed in `pubspec.yaml`. + - *Note:* `firebase-mcp-server` and 12 Firebase agent skills are installed in the agent environment, but the application codebase itself has not yet integrated Firebase. +3. **Explicit Environment Variables:** + - `ANDROID_HOME`, `JAVA_HOME`, and `FLUTTER_ROOT` are not explicitly defined as dedicated environment variables (they resolve via `PATH`). + +--- + +### ⚡ CONFLICT / REDUNDANCY + +1. **Duplicate MCP Server Registrations:** + - `dart` and `dart-mcp-server` are both registered in the MCP environment with identical tool sets (`rip_grep_packages`, `read_package_uris`, `dtd`, `get_runtime_errors`, `hot_restart`, `hot_reload`, `widget_inspector`, `lsp`, `analyze_files`, etc.). + - `stitch` and `StitchMCP` are both registered with identical UI design system tools (`create_project`, `get_project`, `list_screens`, `generate_screen_from_text`, etc.). +2. **Duplicate Workspace Skill Directories:** + - The workspace contains both `.agents/skills/` (65 skills) and `.agent/skills/` (30 skills). All 30 skills in `.agent/` are duplicates of skills in `.agents/`. + +--- + +### 💡 RECOMMENDED ACTIONS + +1. **Standardize Workspace Agent Rules (`AGENTS.md`):** + - Create a single, authoritative `AGENTS.md` at the repository root defining project conventions, the frozen telemetry boundary, Riverpod/Drift state patterns, and testing requirements. +2. **Consolidate Agent Skills Directory:** + - Remove the redundant `.agent/` folder and keep `.agents/` as the single canonical workspace skills directory. +3. **Consolidate Duplicate MCP Registrations:** + - Deduplicate `dart-mcp-server` / `dart` and `StitchMCP` / `stitch` in the MCP configuration to reduce tool schema overhead. +4. **Install Android SDK `cmdline-tools`:** + - Install `Android SDK Command-line Tools (latest)` via Android Studio SDK Manager and run `flutter doctor --android-licenses`. + +--- + +## 3. Telemetry Protection & Architecture Verification + +| Telemetry Subsystem | File Reference | Status | Verification Detail | +| :--- | :--- | :--- | :--- | +| **Telemetry Clock** | [`TelemetryService`](file:///c:/Users/Bill/Desktop/flutter-app/lib/services/telemetry_service.dart) | 🔒 **FROZEN** | `50 ms` periodic acquisition rate (20 Hz) verified across 124,042 frames | +| **Sensor Fusion Math** | [`SensorFusionService`](file:///c:/Users/Bill/Desktop/flutter-app/lib/services/sensor_fusion_service.dart) | 🔒 **FROZEN** | Adaptive Dynamic Complementary Filter with roll rate damping | +| **Speed & Gate Limits** | [`RideStateMachine`](file:///c:/Users/Bill/Desktop/flutter-app/lib/features/rides/ride_state_machine.dart) | 🔒 **FROZEN** | 3.0 MPH moving gate, kickstand isolation, session reset | +| **Data Persistence** | [`AppDatabase`](file:///c:/Users/Bill/Desktop/flutter-app/lib/database/database.dart) | 🔒 **FROZEN** | Drift SQLite batch writer, forensic event storage, Schema 5 | +| **Forensic Export** | [`FieldTestExportService`](file:///c:/Users/Bill/Desktop/flutter-app/lib/services/field_test/field_test_export_service.dart) | 🔒 **FROZEN** | Sub-second CSV, JSON session schema 1, GPX export | +| **Crash Recovery** | [`RideStateMachine`](file:///c:/Users/Bill/Desktop/flutter-app/lib/features/rides/ride_state_machine.dart) | 🔒 **FROZEN** | Unfinished ride detection, power-loss auto-recovery | + +--- + +## 4. "Ready for Development" Checklist + +### Phase 1: Preparation for UI Enhancements +- [x] Static analysis clean (`dart analyze lib test` = 0 issues) +- [x] Full test suite passing (`165/165 tests`) +- [x] Responsive Handling & Dynamics layout verified on all screen sizes +- [x] Interactive forensic event inspection and multi-layer route maps operational +- [x] Data-driven 4-tier motorcycle image hierarchy with isolated fallback operational +- [ ] Connect a physical Android test device or start an Android emulator for visual UI verification + +### Phase 2: Preparation for Account & Authentication Work +- [x] `firebase-mcp-server` active and accessible for cloud provisioning +- [x] Firebase agent skills installed (`firebase-auth-basics`, `firebase-firestore`, `firebase-security-rules-auditor`) +- [ ] Create/select Firebase project via Firebase Console or `firebase-mcp-server` +- [ ] Add `firebase_core` and `firebase_auth` to `pubspec.yaml` without altering telemetry dependencies +- [ ] Generate `lib/firebase_options.dart` using FlutterFire CLI (`flutterfire configure`) +- [ ] Implement authentication repository/state layer strictly outside the frozen telemetry pipeline +- [ ] Maintain offline-first local SQLite operation so telemetry recording never depends on auth state diff --git a/skills-lock.json b/skills-lock.json index d863f82..b50c11e 100644 --- a/skills-lock.json +++ b/skills-lock.json @@ -85,12 +85,216 @@ "skillPath": "skills/caveman-stats/SKILL.md", "computedHash": "57c7db449641379e2afd1389fdb17cec8f33d9c8e25b1d28093937b4431895e8" }, + "dart-add-unit-test": { + "source": "dart-lang/skills", + "sourceType": "github", + "skillPath": "skills/dart-add-unit-test/SKILL.md", + "computedHash": "e5310cd56656f9db8533a612d69e201ee3644dc25f4b10e9ab38d0809440eeb2" + }, + "dart-build-cli-app": { + "source": "dart-lang/skills", + "sourceType": "github", + "skillPath": "skills/dart-build-cli-app/SKILL.md", + "computedHash": "c8cd77f77250ad0783152e180de4fbec149c76e6b2c51c3f0d265a64c7466f0a" + }, + "dart-collect-coverage": { + "source": "dart-lang/skills", + "sourceType": "github", + "skillPath": "skills/dart-collect-coverage/SKILL.md", + "computedHash": "abaf27c3fe7370e4daaea2c48f6efd8cc418042e2844649a9c2979bbfde8b7b1" + }, + "dart-fix-runtime-errors": { + "source": "dart-lang/skills", + "sourceType": "github", + "skillPath": "skills/dart-fix-runtime-errors/SKILL.md", + "computedHash": "5d297ccaf9a34c5939c80600ff8398437c0c6bd5d343093852b65559689fae1d" + }, + "dart-generate-test-mocks": { + "source": "dart-lang/skills", + "sourceType": "github", + "skillPath": "skills/dart-generate-test-mocks/SKILL.md", + "computedHash": "c5132b41dd1d00949d035f6d49fcaee79e95d056eb9652d465e7349f539d16a2" + }, + "dart-migrate-to-checks-package": { + "source": "dart-lang/skills", + "sourceType": "github", + "skillPath": "skills/dart-migrate-to-checks-package/SKILL.md", + "computedHash": "acb9d90dc41fa4410b523e8b60083f1d9fe1dd208c1579260d454c5ab4b3b3f5" + }, + "dart-resolve-package-conflicts": { + "source": "dart-lang/skills", + "sourceType": "github", + "skillPath": "skills/dart-resolve-package-conflicts/SKILL.md", + "computedHash": "4f8029de67b9b2da43eea381c6a320a0da8844d927781effcce6e07ac736dffd" + }, + "dart-run-static-analysis": { + "source": "dart-lang/skills", + "sourceType": "github", + "skillPath": "skills/dart-run-static-analysis/SKILL.md", + "computedHash": "7b143ff93bfb118ce9d72fca56cef4b38d75bfe9044367101db09cf32e6815ad" + }, + "dart-setup-ffi-assets": { + "source": "dart-lang/skills", + "sourceType": "github", + "skillPath": "skills/dart-setup-ffi-assets/SKILL.md", + "computedHash": "d1813c87bd7c556d1aeda275d4b4fa49ce3a3fc19d5d3d8c203c5b9aeaefac51" + }, + "dart-use-doc-examples": { + "source": "dart-lang/skills", + "sourceType": "github", + "skillPath": "skills/dart-use-doc-examples/SKILL.md", + "computedHash": "0b7477a66bd9d767d7d3994c1f08236368baae90250d962bd2ecb2a85237bfd2" + }, + "dart-use-ffigen": { + "source": "dart-lang/skills", + "sourceType": "github", + "skillPath": "skills/dart-use-ffigen/SKILL.md", + "computedHash": "fed0a97615cf80d8fbd59960a7a9d4497ef35af84de618e26492289924cbbcbd" + }, + "dart-use-pattern-matching": { + "source": "dart-lang/skills", + "sourceType": "github", + "skillPath": "skills/dart-use-pattern-matching/SKILL.md", + "computedHash": "4900ea465cfec31cd83d8786491609dc94e338ec8c424a1530773b2aaa0832ff" + }, + "dart-use-primary-constructors": { + "source": "dart-lang/skills", + "sourceType": "github", + "skillPath": "skills/dart-use-primary-constructors/SKILL.md", + "computedHash": "f3a388b5b11b2d3b6b6c494e2cc0fbd6c4f670b9bdeb97b024f4d18b4c1970f5" + }, + "dart-write-documentation": { + "source": "dart-lang/skills", + "sourceType": "github", + "skillPath": "skills/dart-write-documentation/SKILL.md", + "computedHash": "2c6cf741f5424f7f3ed805a09ec0c46b668bb9f9c2861988b3da42e558e5ae95" + }, + "extension-to-functions-codebase": { + "source": "firebase/agent-skills", + "sourceType": "github", + "skillPath": "skills/extension-to-functions-codebase/SKILL.md", + "computedHash": "1b0b4150895374330ff51a6f0d99663eda4d266730802eec85882443aeca9539" + }, + "firebase-ai-logic-basics": { + "source": "firebase/agent-skills", + "sourceType": "github", + "skillPath": "skills/firebase-ai-logic-basics/SKILL.md", + "computedHash": "bab9220a5f6c214310adb2aa8ed267463719574209d9e0429426d168d43f27a5" + }, + "firebase-app-hosting-basics": { + "source": "firebase/agent-skills", + "sourceType": "github", + "skillPath": "skills/firebase-app-hosting-basics/SKILL.md", + "computedHash": "052ef64fe35efdf02b7e0dc121abc09b1514e8b228454ab2002af31448c0a212" + }, + "firebase-auth-basics": { + "source": "firebase/agent-skills", + "sourceType": "github", + "skillPath": "skills/firebase-auth-basics/SKILL.md", + "computedHash": "c2eead02bc534bd12d7d3bc8f7d99e10dc44ab13f416d1c5293df38ecc2f6848" + }, + "firebase-basics": { + "source": "firebase/agent-skills", + "sourceType": "github", + "skillPath": "skills/firebase-basics/SKILL.md", + "computedHash": "c0e06c4f5be407fcf74c9b76c91a4f87cac653a07c639904f82424fc4dbbe864" + }, + "firebase-crashlytics": { + "source": "firebase/agent-skills", + "sourceType": "github", + "skillPath": "skills/firebase-crashlytics/SKILL.md", + "computedHash": "15c3cca501773a8e29ea852b6d3a2e5dcc9d43d1e69a0d85a6b0eae82c6ac2cc" + }, + "firebase-data-connect": { + "source": "firebase/agent-skills", + "sourceType": "github", + "skillPath": "skills/firebase-data-connect-basics/SKILL.md", + "computedHash": "72a5f0c53909db6a7bd9237e74eccfff0d469bbe6df5126e25f019627fa0583c" + }, + "firebase-firestore": { + "source": "firebase/agent-skills", + "sourceType": "github", + "skillPath": "skills/firebase-firestore/SKILL.md", + "computedHash": "090565389f17369f9c97cbe8d76c4ac7f0b93254c52fbc2f1d10f8234ad63500" + }, + "firebase-hosting-basics": { + "source": "firebase/agent-skills", + "sourceType": "github", + "skillPath": "skills/firebase-hosting-basics/SKILL.md", + "computedHash": "3df1714a23bde9fbce5c0e6fb7ce4502a0a88e5fbcf2e1ad341deb1b9e648e67" + }, + "firebase-remote-config-basics": { + "source": "firebase/agent-skills", + "sourceType": "github", + "skillPath": "skills/firebase-remote-config-basics/SKILL.md", + "computedHash": "4a6e2f5ce701c81ac75c138f2fbae0f9ec9159b5c67c825ee173dfe6147da9ee" + }, + "firebase-security-rules-auditor": { + "source": "firebase/agent-skills", + "sourceType": "github", + "skillPath": "skills/firebase-security-rules-auditor/SKILL.md", + "computedHash": "be877f6c7aaf460791dd6103a08906734036c26bd7c686cfdb8b60e4b2f65742" + }, + "flutter-add-integration-test": { + "source": "flutter/agent-plugins", + "sourceType": "github", + "skillPath": "skills/flutter-add-integration-test/SKILL.md", + "computedHash": "4246d3ef5f21bdb7945899056b99cf3863e2bff645a132b41634caaded68da6d" + }, + "flutter-add-widget-preview": { + "source": "flutter/agent-plugins", + "sourceType": "github", + "skillPath": "skills/flutter-add-widget-preview/SKILL.md", + "computedHash": "369ed3ebdc1f81ee337551ad1d1dd9ec6e768ed2bdf65d32ad442117a6ba79b6" + }, + "flutter-add-widget-test": { + "source": "flutter/agent-plugins", + "sourceType": "github", + "skillPath": "skills/flutter-add-widget-test/SKILL.md", + "computedHash": "f4ea905ae155d1bca76f5431bf6ed31f31e3d40146493e7ae4285eac39ba4ffd" + }, + "flutter-apply-architecture-best-practices": { + "source": "flutter/agent-plugins", + "sourceType": "github", + "skillPath": "skills/flutter-apply-architecture-best-practices/SKILL.md", + "computedHash": "baeb208b1cab90c559677626dbd101b96ba93f803cbed85122abdadeb3283a8b" + }, "flutter-build-responsive-layout": { - "source": "flutter/skills", + "source": "flutter/agent-plugins", "sourceType": "github", "skillPath": "skills/flutter-build-responsive-layout/SKILL.md", "computedHash": "6d74a9504c4e355c4c62f6fcb6c6dc0df67b56dd6616bea199e4e58f75b7729b" }, + "flutter-fix-layout-issues": { + "source": "flutter/agent-plugins", + "sourceType": "github", + "skillPath": "skills/flutter-fix-layout-issues/SKILL.md", + "computedHash": "b2f9789451224e6df8d1d7ac63854c2f1beb30fa35d13ea06fbae9ba2b1b0a7f" + }, + "flutter-implement-json-serialization": { + "source": "flutter/agent-plugins", + "sourceType": "github", + "skillPath": "skills/flutter-implement-json-serialization/SKILL.md", + "computedHash": "c2cf46854472a452dafa11f862f2bca3d9fe7286a5bb45d85b1efbcebc74b74e" + }, + "flutter-setup-declarative-routing": { + "source": "flutter/agent-plugins", + "sourceType": "github", + "skillPath": "skills/flutter-setup-declarative-routing/SKILL.md", + "computedHash": "4c2ed2fd729230be581b15d84741688e206632fb2b38af320060cd3518b91179" + }, + "flutter-setup-localization": { + "source": "flutter/agent-plugins", + "sourceType": "github", + "skillPath": "skills/flutter-setup-localization/SKILL.md", + "computedHash": "fc0811b1b775c52c1b8f7df600f5c52b83029aea0586b8cc55169812affd408f" + }, + "flutter-use-http-package": { + "source": "flutter/agent-plugins", + "sourceType": "github", + "skillPath": "skills/flutter-use-http-package/SKILL.md", + "computedHash": "bd169b5cee731751f3b32f43c94cfe9495fc8e6c3eb621b785c69e38b77d0e19" + }, "gws-drive": { "source": "googleworkspace/cli", "sourceType": "github", @@ -144,6 +348,12 @@ "sourceType": "github", "skillPath": "skills/verify-and-stop/SKILL.md", "computedHash": "3d67de16a2b3c48b643bc511ebc4cb86e6c7105215d8428b6140cbcb73aba4e6" + }, + "xcode-project-setup": { + "source": "firebase/agent-skills", + "sourceType": "github", + "skillPath": "skills/xcode-project-setup/SKILL.md", + "computedHash": "673e1c3a078c3a77c4ae706ddc731c9efc5d151b82097ef52f10c575e4cdc1c1" } } }