Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
name: Cross-platform build and tests

on:
push:
branches:
- main
- "codex/**"
pull_request:

concurrency:
group: cross-platform-${{ github.ref }}
cancel-in-progress: true

jobs:
android:
name: Android unit tests and debug APK
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "17"
cache: gradle
- name: Test and assemble PlayerAgent
run: bash ./gradlew :PlayerAgentApp:testDebugUnitTest :PlayerAgentApp:assembleDebug
- name: Test and assemble Android Controller
run: bash ./gradlew :ControllerApp:testDebugUnitTest :ControllerApp:assembleDebug
- uses: actions/upload-artifact@v4
with:
name: PlayerAgent-debug-apk
path: PlayerAgentApp/build/outputs/apk/debug/*.apk
- uses: actions/upload-artifact@v4
with:
name: Controller-debug-apk
path: ControllerApp/build/outputs/apk/debug/*.apk

ios:
name: iOS simulator XCTest
runs-on: macos-15
timeout-minutes: 35
steps:
- uses: actions/checkout@v4
- name: Inspect Xcode and available simulators
run: |
xcodebuild -version
xcrun simctl list devices available
- name: Run unsigned simulator tests
run: |
set -euo pipefail
simulator_udid="$(
xcrun simctl list devices available -j |
python3 -c '
import json
import sys

runtimes = json.load(sys.stdin).get("devices", {})
devices = (
device
for runtime_devices in runtimes.values()
for device in runtime_devices
)
print(next(
device["udid"]
for device in devices
if device.get("isAvailable") and device.get("name", "").startswith("iPhone")
))
'
)"
echo "Using iOS simulator: ${simulator_udid}"
run_ios_tests() {
local attempt="$1"
xcodebuild \
-project IOSBleFeasibility/IOSBleFeasibility.xcodeproj \
-scheme sonyMusic \
-destination "platform=iOS Simulator,id=${simulator_udid}" \
-derivedDataPath "${RUNNER_TEMP}/IOSBleFeasibilityDerivedData-${attempt}" \
-parallel-testing-enabled NO \
CODE_SIGNING_ALLOWED=NO \
test
}
if ! run_ios_tests 1; then
echo "::warning::iOS simulator test attempt 1 failed; restarting the simulator and retrying once"
xcrun simctl shutdown "${simulator_udid}" || true
run_ios_tests 2
fi
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ Thumbs.db

# Logs
*.log
*.hprof

# Local deploy state
tools/deploy/last_deploy.json
tools/deploy/last_successful_deploy.json
23 changes: 23 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Codebase Memory 工作约定

本仓库已使用 `codebase-memory-mcp` 建立本地代码知识图谱。当前索引项目名为
`Volumes-e99bb7e794b5-project-MusicBleController`。

## 修改前先查索引

对代码进行修改、重构、性能优化或缺陷排查前:

1. 先调用 `list_projects`,并用 `index_status` 确认当前仓库索引可用。
2. 索引不存在、状态异常或结果明显陈旧时,调用 `index_repository`,对当前仓库执行完整索引;除非用户明确要求,不生成仓库内持久化图谱文件。
3. 使用 `get_architecture` 或 `search_graph` 定位模块、类型和符号。
4. 涉及调用关系、数据流或影响范围时,使用 `trace_path` 和 `detect_changes`。
5. 使用 `get_code_snippet` 获取精确符号位置,然后必须读取真实源文件再编辑。

## 验证原则

- 图谱用于结构化发现,不是编译器或测试结果的替代品。
- 反射、依赖注入、系统回调、动态分派和生成代码可能无法完整建图;重要结论必须用源码、`rg`、构建和测试验证。
- 字符串、错误信息、配置、脚本和非代码文件可直接使用 `rg`/文件读取工具搜索。
- 不得仅凭空结果断言“没有调用者”“未使用”或“无影响”;这类结论必须补充源码搜索。
- 编辑后使用 `detect_changes` 检查结构影响,并运行与改动相关的测试或构建。
- 如果编辑后的图谱结果仍显示旧代码,重新运行 `index_repository` 后再继续分析。
56 changes: 54 additions & 2 deletions ControllerApp/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
apply plugin: 'com.android.application'
apply plugin: 'org.jetbrains.kotlin.android'
apply plugin: 'kotlin-kapt'

android {
namespace 'com.example.controllerapp'
Expand All @@ -9,8 +10,10 @@ android {
applicationId 'com.example.controllerapp'
minSdk 23
targetSdk 35
versionCode 1
versionName '1.0'
versionCode 2
versionName '2.0'

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

compileOptions {
Expand All @@ -21,4 +24,53 @@ android {
kotlinOptions {
jvmTarget = '1.8'
}

buildFeatures {
compose true
}

composeOptions {
kotlinCompilerExtensionVersion '1.5.14'
}

packagingOptions {
resources {
excludes += '/META-INF/{AL2.0,LGPL2.1}'
}
}
}

dependencies {
def composeBom = platform("androidx.compose:compose-bom:2024.06.00")
implementation composeBom
androidTestImplementation composeBom

implementation "androidx.core:core-ktx:1.13.1"
implementation "androidx.activity:activity-compose:1.9.0"
implementation "androidx.compose.ui:ui"
implementation "androidx.compose.ui:ui-tooling-preview"
implementation "androidx.compose.material3:material3"
implementation "androidx.compose.material:material-icons-extended"
implementation "androidx.navigation:navigation-compose:2.7.7"
implementation "androidx.lifecycle:lifecycle-runtime-compose:2.8.3"
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.8.3"
implementation "androidx.datastore:datastore-preferences:1.1.1"
implementation "androidx.room:room-runtime:2.6.1"
implementation "androidx.room:room-ktx:2.6.1"
implementation "androidx.media:media:1.7.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1"
kapt "androidx.room:room-compiler:2.6.1"

debugImplementation "androidx.compose.ui:ui-tooling"
debugImplementation "androidx.compose.ui:ui-test-manifest"

testImplementation "junit:junit:4.13.2"
testImplementation "org.json:json:20240303"
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.1"

androidTestImplementation "androidx.test:core:1.7.0"
androidTestImplementation "androidx.test:runner:1.7.0"
androidTestImplementation "androidx.test.ext:junit:1.3.0"
androidTestImplementation "androidx.test.espresso:espresso-core:3.7.0"
androidTestImplementation "androidx.compose.ui:ui-test-junit4"
}
Loading
Loading