docs: add AGENTS.md skeleton #1
Reference in New Issue
Block a user
Delete Branch "docs/agents-md-tier-1"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
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.