Adds an AGENTS.md skeleton for AI coding agents (Claude Code, Aider, Cursor, etc.), per the 2026-05-21 doc audit (Tier-1 sweep). Repo-specific tech stack, conventions, file layout, and domain gotchas.
Generated with Claude Code.
Adds an AGENTS.md skeleton for AI coding agents (Claude Code, Aider, Cursor, etc.), per the 2026-05-21 doc audit (Tier-1 sweep). Repo-specific tech stack, conventions, file layout, and domain gotchas.
Generated with Claude Code.
copilot-pull-request-reviewer[bot]
(Migrated from github.com)
reviewed 2026-05-21 10:45:14 +00:00
copilot-pull-request-reviewer[bot]
(Migrated from github.com)
left a comment
Copy Link
Copy Source
Pull request overview
This PR introduces a new set of cross-project components for the AV-Live body pipeline (shared wire format + USB transport, new macOS/iOS clients, and Python-side ARKit/LiDAR fusion), and adds an AGENTS.md guidance document for AI coding agents.
Changes:
Add shared/AVLiveWire Swift package (frame header, stream demuxer, wire payloads) with unit tests.
Add/extend body-tracking clients: iOS iphone-arbody (USB server + HEVC encoder) and macOS avlivebody-mac (usbmuxd client, RealityKit scene, optional Multi-HMR CoreML).
Add Python ARKit joint ingestion, ICP LiDAR fusion plumbing, and a new data_feeds/ OSC publisher package; update docs and repo ignores.
Reviewed changes
Copilot reviewed 130 out of 146 changed files in this pull request and generated 10 comments.
The PR title/description says it's a docs-only change adding an AGENTS.md skeleton, but this PR also introduces substantial new Swift/Python code (AVLiveWire package, iOS/macOS apps, ICP fusion pipeline, etc.). Please update the PR title/description to reflect the actual scope, or split the docs addition into a separate PR so reviewers can assess the code changes independently.
The PR title/description says it's a docs-only change adding an `AGENTS.md` skeleton, but this PR also introduces substantial new Swift/Python code (AVLiveWire package, iOS/macOS apps, ICP fusion pipeline, etc.). Please update the PR title/description to reflect the actual scope, or split the docs addition into a separate PR so reviewers can assess the code changes independently.
The command open avlivebody-mac/avlivebody.xcodeproj appears incorrect/inconsistent with the avlivebody-mac docs and project.yml (project name is AVLiveBody.xcodeproj, and it is generated/ignored). This should point to the generated AVLiveBody.xcodeproj after running xcodegen generate, otherwise new contributors will hit a dead path.
The command `open avlivebody-mac/avlivebody.xcodeproj` appears incorrect/inconsistent with the `avlivebody-mac` docs and `project.yml` (project name is `AVLiveBody.xcodeproj`, and it is generated/ignored). This should point to the generated `AVLiveBody.xcodeproj` after running `xcodegen generate`, otherwise new contributors will hit a dead path.
The doc comment says the conversion keeps y pointing up ("y up" -> "y up"), but the implementation negates y (SIMD3(v.x, -v.y, -v.z)). Please either fix the comment to match the actual transform, or adjust the transform so it matches the documented axis convention (otherwise it’s easy to apply the wrong transform across the codebase).
The doc comment says the conversion keeps `y` pointing up ("y up" -> "y up"), but the implementation negates `y` (`SIMD3(v.x, -v.y, -v.z)`). Please either fix the comment to match the actual transform, or adjust the transform so it matches the documented axis convention (otherwise it’s easy to apply the wrong transform across the codebase).
IcpFusionThread writes to shared state (lidar_points, lidar_timestamp_ns, icp_metadata, and potentially persons_smplx[*].vertices_3d via run_once) without holding state.lock(). This contradicts the codebase’s stated threading invariant (and risks races with other workers/UI readers). Please stage/copy the LiDAR frame outside the lock if needed, but wrap all state mutations (including the in-place mesh update) in a with state.lock(): block or introduce a dedicated lock for these fields.
`IcpFusionThread` writes to shared `state` (`lidar_points`, `lidar_timestamp_ns`, `icp_metadata`, and potentially `persons_smplx[*].vertices_3d` via `run_once`) without holding `state.lock()`. This contradicts the codebase’s stated threading invariant (and risks races with other workers/UI readers). Please stage/copy the LiDAR frame outside the lock if needed, but wrap all `state` mutations (including the in-place mesh update) in a `with state.lock():` block or introduce a dedicated lock for these fields.
The iPhone OSC listener (self._iphone_osc) is started in _start_pose_worker, but it is not stopped in applicationWillTerminate_. This can leave a background OSC server thread running during shutdown. Please add a guarded stop/shutdown here (similar to the ICP fusion thread stop) to ensure clean termination.
The iPhone OSC listener (`self._iphone_osc`) is started in `_start_pose_worker`, but it is not stopped in `applicationWillTerminate_`. This can leave a background OSC server thread running during shutdown. Please add a guarded stop/shutdown here (similar to the ICP fusion thread stop) to ensure clean termination.
The comments describe per-pid/per-side "companion arrays" for hand meshes (including a per-hand last-update timestamp), but persons_hands_mesh_last_t is a single float. If the intent is per-pid/per-side freshness tracking, this should likely be a dict keyed by pid/side (or the comment should be updated to reflect a single global timestamp).
The comments describe per-pid/per-side "companion arrays" for hand meshes (including a per-hand last-update timestamp), but `persons_hands_mesh_last_t` is a single float. If the intent is per-pid/per-side freshness tracking, this should likely be a dict keyed by pid/side (or the comment should be updated to reflect a single global timestamp).
This test name says returns_none_when_coreml_unavailable, but the assertion expects predict_once to raise NotImplementedError. Either rename the test to match the current behavior, or (if the intended API is to return None) update the implementation and assert accordingly so the test communicates the contract clearly.
This test name says `returns_none_when_coreml_unavailable`, but the assertion expects `predict_once` to raise `NotImplementedError`. Either rename the test to match the current behavior, or (if the intended API is to return `None`) update the implementation and assert accordingly so the test communicates the contract clearly.
This .swiftpm/xcode/.../contents.xcworkspacedata file is an Xcode/SwiftPM generated artifact. Since .swiftpm/ is already being gitignored, this file should be removed from version control to avoid churn and machine-specific workspace state being committed.
This `.swiftpm/xcode/.../contents.xcworkspacedata` file is an Xcode/SwiftPM generated artifact. Since `.swiftpm/` is already being gitignored, this file should be removed from version control to avoid churn and machine-specific workspace state being committed.
Config/Local.xcconfig contains a concrete DEVELOPMENT_TEAM value. This file is meant to be developer-local (the repo docs and .gitignore indicate it should be gitignored) and committing a real Team ID can leak personal/org signing configuration. Please remove this file from the repo and keep only Local.xcconfig.example committed.
`Config/Local.xcconfig` contains a concrete `DEVELOPMENT_TEAM` value. This file is meant to be developer-local (the repo docs and `.gitignore` indicate it should be gitignored) and committing a real Team ID can leak personal/org signing configuration. Please remove this file from the repo and keep only `Local.xcconfig.example` committed.
If FrameHeader(decoding:) returns nil while findMagic() found magic at offset 0 and buffer.count >= byteCount, feed currently breaks, leaving the corrupt header at the front of the buffer forever and preventing resynchronization (even if valid frames follow). Instead of breaking, treat this as a corrupt header and advance the buffer (e.g., drop 1 byte or magic.count) and continue searching for the next magic sequence.
If `FrameHeader(decoding:)` returns nil while `findMagic()` found magic at offset 0 and `buffer.count >= byteCount`, `feed` currently `break`s, leaving the corrupt header at the front of the buffer forever and preventing resynchronization (even if valid frames follow). Instead of breaking, treat this as a corrupt header and advance the buffer (e.g., drop 1 byte or `magic.count`) and continue searching for the next magic sequence.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Adds an AGENTS.md skeleton for AI coding agents (Claude Code, Aider, Cursor, etc.), per the 2026-05-21 doc audit (Tier-1 sweep). Repo-specific tech stack, conventions, file layout, and domain gotchas.
Generated with Claude Code.
Pull request overview
This PR introduces a new set of cross-project components for the AV-Live body pipeline (shared wire format + USB transport, new macOS/iOS clients, and Python-side ARKit/LiDAR fusion), and adds an
AGENTS.mdguidance document for AI coding agents.Changes:
shared/AVLiveWireSwift package (frame header, stream demuxer, wire payloads) with unit tests.iphone-arbody(USB server + HEVC encoder) and macOSavlivebody-mac(usbmuxd client, RealityKit scene, optional Multi-HMR CoreML).data_feeds/OSC publisher package; update docs and repo ignores.Reviewed changes
Copilot reviewed 130 out of 146 changed files in this pull request and generated 10 comments.
Show a summary per file
lidarextra with Open3D constraintFiles not reviewed (1)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
@@ -0,0 +5,4 @@## Project`AV-Live` — live-coding audio-visual performance system: SuperCollider sound engine, openFrameworks visualiser driven by a Hantek 6022BL oscilloscope, and a SwiftUI menubar launcher orchestrating everything. Public, GPL-3. Repo `electron-rare/AV-Live`, branch `main`. Multi-host: GrosMac (source), macm1 (sink / Multi-HMR + Apple Vision ANE), iPhone 16 Pro (ARKit/LiDAR pub).The PR title/description says it's a docs-only change adding an
AGENTS.mdskeleton, but this PR also introduces substantial new Swift/Python code (AVLiveWire package, iOS/macOS apps, ICP fusion pipeline, etc.). Please update the PR title/description to reflect the actual scope, or split the docs addition into a separate PR so reviewers can assess the code changes independently.@@ -0,0 +34,4 @@# Swiftopen launcher/Package.swift # or xcodebuild from CLIopen avlivebody-mac/avlivebody.xcodeprojThe command
open avlivebody-mac/avlivebody.xcodeprojappears incorrect/inconsistent with theavlivebody-macdocs andproject.yml(project name isAVLiveBody.xcodeproj, and it is generated/ignored). This should point to the generatedAVLiveBody.xcodeprojafter runningxcodegen generate, otherwise new contributors will hit a dead path.@@ -0,0 +7,4 @@@inline(__always)func arkitToRealityKit(_ v: SIMD3<Float>) -> SIMD3<Float> {SIMD3<Float>(v.x, -v.y, -v.z)}The doc comment says the conversion keeps
ypointing up ("y up" -> "y up"), but the implementation negatesy(SIMD3(v.x, -v.y, -v.z)). Please either fix the comment to match the actual transform, or adjust the transform so it matches the documented axis convention (otherwise it’s easy to apply the wrong transform across the codebase).@@ -0,0 +63,4 @@self._state.lidar_timestamp_ns = frame.timestamp_nstry:self._state.icp_metadata = self._worker.run_once(self._state)IcpFusionThreadwrites to sharedstate(lidar_points,lidar_timestamp_ns,icp_metadata, and potentiallypersons_smplx[*].vertices_3dviarun_once) without holdingstate.lock(). This contradicts the codebase’s stated threading invariant (and risks races with other workers/UI readers). Please stage/copy the LiDAR frame outside the lock if needed, but wrap allstatemutations (including the in-place mesh update) in awith state.lock():block or introduce a dedicated lock for these fields.@@ -585,6 +619,12 @@ class AppDelegate(NSObject):self._listener.stop()The iPhone OSC listener (
self._iphone_osc) is started in_start_pose_worker, but it is not stopped inapplicationWillTerminate_. This can leave a background OSC server thread running during shutdown. Please add a guarded stop/shutdown here (similar to the ICP fusion thread stop) to ensure clean termination.@@ -122,0 +132,4 @@persons_hands_mesh: dict = field(default_factory=dict)persons_hands_mesh_cam_t: dict = field(default_factory=dict)persons_hands_mesh_last_t: float = 0.0The comments describe per-pid/per-side "companion arrays" for hand meshes (including a per-hand last-update timestamp), but
persons_hands_mesh_last_tis a single float. If the intent is per-pid/per-side freshness tracking, this should likely be a dict keyed by pid/side (or the comment should be updated to reflect a single global timestamp).@@ -54,0 +63,4 @@import pytest, numpy as nprgb = np.zeros((480, 640, 3), dtype=np.uint8)with pytest.raises(NotImplementedError):worker.predict_once(rgb)This test name says
returns_none_when_coreml_unavailable, but the assertion expectspredict_onceto raiseNotImplementedError. Either rename the test to match the current behavior, or (if the intended API is to returnNone) update the implementation and assert accordingly so the test communicates the contract clearly.@@ -0,0 +4,4 @@<FileReflocation = "self:"></FileRef></Workspace>This
.swiftpm/xcode/.../contents.xcworkspacedatafile is an Xcode/SwiftPM generated artifact. Since.swiftpm/is already being gitignored, this file should be removed from version control to avoid churn and machine-specific workspace state being committed.@@ -0,0 +1 @@DEVELOPMENT_TEAM = K9KK43329XConfig/Local.xcconfigcontains a concreteDEVELOPMENT_TEAMvalue. This file is meant to be developer-local (the repo docs and.gitignoreindicate it should be gitignored) and committing a real Team ID can leak personal/org signing configuration. Please remove this file from the repo and keep onlyLocal.xcconfig.examplecommitted.@@ -0,0 +28,4 @@if start > 0 { buffer.removeFirst(start) }guard buffer.count >= FrameHeader.byteCount,let h = FrameHeader(decoding: buffer) else { break }if h.length > Self.maxPayloadLength {If
FrameHeader(decoding:)returns nil whilefindMagic()found magic at offset 0 andbuffer.count >= byteCount,feedcurrentlybreaks, leaving the corrupt header at the front of the buffer forever and preventing resynchronization (even if valid frames follow). Instead of breaking, treat this as a corrupt header and advance the buffer (e.g., drop 1 byte ormagic.count) and continue searching for the next magic sequence.