Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
45f1f27
Polish beauty panel layout and clean up resources
Apr 29, 2026
081563a
chore(android): standardize case skill system across example apps
May 7, 2026
e68da28
Update LiveStreaming watermark API
May 26, 2026
2bc2503
Add ScreenSharing permission callback
May 26, 2026
d5868bc
Update audio scenario options
May 26, 2026
25b2768
Expose audio route options
May 26, 2026
df7d225
Expose video module position option
May 26, 2026
c6616b7
Handle token state changes in JoinChannelVideoByToken
May 27, 2026
414e1a9
Hide deprecated RhythmPlayer from UI list
May 27, 2026
7a7ebb8
Merge branch 'main' into dev/4.6.4
Jul 15, 2026
6aa1661
feat(ai-engineering): add multi-platform API Example iteration workfl…
alienzh Jul 28, 2026
8b12b74
Codex/4.7.0 release iteration (#479)
alienzh Jul 31, 2026
0bbd47a
fix: use EglBaseLock for FaceUnity rendering (#480)
alienzh Aug 3, 2026
7f0322b
Merge branch 'main' into dev/4.7.0
Aug 4, 2026
eadeff6
Dev/4.7.0 agorabeauty (#481)
alienzh Aug 5, 2026
d235fcb
Codex/4.7.0 mac ci download order (#482)
alienzh Aug 5, 2026
d5bc8d4
fix: adapt Agora Beauty 2.0 to video effect APIs
Aug 5, 2026
7c6576b
fix(android): adapt examples to RTC SDK 4.7.0
Aug 7, 2026
de03dcb
fix(ios): adapt examples to RTC SDK 4.7.0
Aug 7, 2026
0c17569
chore(android): remove face capture example
Aug 7, 2026
d918e6c
fix(macos): adapt examples to RTC SDK 4.7.0
Aug 7, 2026
2bb3f14
chore(android): hide deprecated rhythm player examples
Aug 7, 2026
15034f9
chore(ios): remove deprecated face capture examples
Aug 7, 2026
d5bd7ae
feat: update Windows examples for RTC SDK 4.7.0
Aug 7, 2026
784f4d4
docs: support hidden API example cases
Aug 7, 2026
eaf511a
feat(android): add SenseTime beauty example
Aug 10, 2026
7197a6d
feat(ios): add SenseTime beauty example
Aug 10, 2026
4bd0ba6
fix(ios): download beauty resources from Artifactory
Aug 10, 2026
a81b10e
feat(android): update agora beauty
Aug 11, 2026
e270056
fix(windows): correct audio mixing resource path
Aug 12, 2026
00fb6b1
fix(windows): correct packaged resource paths
Aug 13, 2026
ee77cc8
fix(windows): package custom video sample
Aug 14, 2026
3597cd3
chore: standardize agent assets and harden release checks
Aug 20, 2026
9b1b584
chore: update ai-engineering
Aug 25, 2026
14547da
Merge branch 'main' into dev/4.7.0
Sep 3, 2026
fcb79cc
fix: refine RTC 4.7.0 example compatibility
Sep 7, 2026
b1c2532
fix: address Android 4.7.0 build blockers
Sep 7, 2026
f5695ee
fix: address RTC 4.7.0 review findings
Sep 7, 2026
b64b6d0
chore: update RTC SDK headers for 4.7.0
Sep 8, 2026
989d3eb
fix(android): correct FFmpeg library name
Sep 8, 2026
282815b
ci: align Agora APIExample package contents
Sep 8, 2026
da9c615
chore: streamline repository git hooks
Sep 8, 2026
0bd5372
refactor: streamline AI engineering assets and retire Azure CI
Sep 8, 2026
2cf62f6
refactor(ci): remove obsolete cloud project scripts
Sep 9, 2026
10afcd3
docs: refresh RTC documentation links
Sep 9, 2026
1734024
fix: harden AI templates and align example names
Sep 10, 2026
0448b60
refactor(macos): modernize screen capture and require macOS 12
Sep 17, 2026
481ac65
fix(ios): adopt scene lifecycle while preserving iOS 12
Sep 17, 2026
59235ae
fix(ios): support Xcode 27 and adapt audio call layout
Sep 17, 2026
d6f8c8a
build(android): migrate RTC dependencies to official Maven repositories
Sep 22, 2026
437a0ed
fix(ci): align lightweight pull request compile checks
Sep 22, 2026
9f0bcd0
fix(ios): disable optional beauty pods in public CI
Oct 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
91 changes: 91 additions & 0 deletions .agents/skills/cross-platform-api-change/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
---
name: cross-platform-api-change
description: Coordinate an RTC API Examples change across Android, iOS, macOS, and Windows when behavior, SDK usage, dependencies, CI, or packaging may affect more than one project.
---

# Cross-Platform API Change

Use one written contract to keep every affected implementation aligned. The contract is
the source of truth for behavior; an existing platform implementation is only a reference.

## Required Context

1. Read the root `AGENTS.md`.
2. Read `docs/ai/README.md`, `docs/ai/change-contract-template.md`, and
`docs/ai/project-matrix.md`.
3. For SDK, dependency, CI, packaging, signing, or external-asset changes, also read
`docs/ai/release-risks.md`.
4. Read the platform and project `AGENTS.md` and `ARCHITECTURE.md` files for every project
that may be affected.

Treat the current source tree as the case inventory. Do not rely on a separately maintained
case catalog.

## Workflow

### 1. Establish The Contract

Before editing, copy `docs/ai/change-contract-template.md` into the issue, pull request, or
task notes and complete it. Define observable behavior, SDK operations, inputs and defaults,
callbacks, success and failure signals, lifecycle cleanup, non-goals, and the reference
implementation or documentation.

Separate shared behavior from platform-specific API and UI details. If the requirement
changes, update the contract first and then re-evaluate scope and existing work.

### 2. Decide Every Project

Review every row in `docs/ai/project-matrix.md`. Mark each project `REQUIRED`,
`REVIEW_ONLY`, or `NOT_APPLICABLE`. Include a reason for every project that is not required.
Do not assume that Android Views covers Compose, iOS UIKit covers SwiftUI or Objective-C,
or a full-SDK project covers its audio-only counterpart.

### 3. Implement From The Same Contract

One coordinator owns the contract and cross-platform decisions. Split implementation by
top-level platform only when parallel work is explicitly available, and give every owner
the same contract, its project scope, allowed paths, reference, and validation requirements.
Platform owners must not redefine shared behavior.

Implementations may differ because of SDK types, UI frameworks, permissions, or operating
system behavior. Record each intentional difference and its reason in the contract.

### 4. Verify Each Required Project

For every required project:

- compare the diff with the shared contract;
- verify SDK arguments, defaults, callbacks, lifecycle, threading, errors, registration,
resources, localization, and cleanup as applicable;
- run the strongest valid build or static check documented by that project;
- record changed files, commands, results, blockers, and intentional differences.

Keep scope decisions and validation status separate. Record each planned validation as one
of:

- `PASS`: the command or behavioral check completed and met its acceptance criteria;
- `FAIL`: the check ran and failed;
- `BLOCKED`: the check cannot run yet; record the blocker, remaining command, and the
condition that will unblock it;
- `NOT_RUN`: the check was not attempted; record why.

Do not convert `BLOCKED` or `NOT_RUN` into a pass. They are valid handoff states, but they
leave the overall change incomplete.

Compilation is necessary but does not prove behavioral parity. Use an independent review
pass when available.

### 5. Close Cross-Platform Acceptance

The change is complete only when every project has an explicit scope decision, every
required implementation satisfies the contract, and every required validation is `PASS`.
A change with `FAIL`, `BLOCKED`, or `NOT_RUN` validation may be handed off with clear next
steps, but must not be reported as complete. Copy the final scope, differences, and
validation evidence into the pull request using `.github/pull_request_template.md`.

Before handoff, confirm that SDK sources match `docs/ai/project-matrix.md` and that no real
App ID, certificate, token, signing asset, private key, or private download URL is staged.

Do not commit task transcripts, agent identities, generated case catalogs, prompt snapshots,
or run logs. Preserve durable product behavior and verification evidence in the issue or
pull request.
58 changes: 37 additions & 21 deletions .git-hooks/check-commit-message.sh
Original file line number Diff line number Diff line change
@@ -1,22 +1,38 @@
#!/bin/bash

commit_msg_file=$1
commit_msg=$(cat "$commit_msg_file")


if perl -e '
binmode(STDIN, ":utf8");
$/ = undef;
$text = <>;
if ($text =~ /[\x{4e00}-\x{9fff}]/) {
exit(1);
} else {
exit(0);
}' < "$commit_msg_file"
then
exit 0
else
echo "Error: Commit message contains Chinese characters."
echo "Please use English only in commit messages."
#!/usr/bin/env bash

set -euo pipefail

if [[ $# -ne 1 || ! -f "$1" ]]; then
echo "Error: expected a commit message file." >&2
exit 1
fi
fi

if ! command -v python3 >/dev/null 2>&1; then
echo "Error: python3 is required to validate commit messages." >&2
exit 1
fi

python3 - "$1" <<'PY'
import pathlib
import sys


han_ranges = (
(0x3400, 0x4DBF),
(0x4E00, 0x9FFF),
(0xF900, 0xFAFF),
(0x20000, 0x2EBEF),
(0x30000, 0x323AF),
)

try:
message = pathlib.Path(sys.argv[1]).read_text(encoding="utf-8")
except (OSError, UnicodeError) as error:
print(f"Error: cannot read commit message as UTF-8: {error}", file=sys.stderr)
raise SystemExit(1)

if any(start <= ord(character) <= end for character in message for start, end in han_ranges):
print("Error: commit message contains Chinese characters.", file=sys.stderr)
print("Please use English only in commit messages.", file=sys.stderr)
raise SystemExit(1)
PY
212 changes: 67 additions & 145 deletions .git-hooks/install-hooks.sh
Original file line number Diff line number Diff line change
@@ -1,165 +1,87 @@
#!/bin/bash

# Functions for colored text output
print_green() {
echo -e "\033[0;32m$1\033[0m"
}

print_yellow() {
echo -e "\033[0;33m$1\033[0m"
}

print_red() {
echo -e "\033[0;31m$1\033[0m"
}

# Function to add executable permissions
ensure_executable() {
if [ -f "$1" ] && [ ! -x "$1" ]; then
chmod +x "$1"
print_green "Added executable permission to $1"
fi
}

# Ensure script runs from project root directory
if [ ! -d ".git" ]; then
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$(dirname "$SCRIPT_DIR")" || { print_red "Cannot find project root directory"; exit 1; }

if [ ! -d ".git" ]; then
print_red "Please run this script from the project root directory"
exit 1
fi
fi
#!/usr/bin/env bash

# Check if pre-commit is installed
if ! command -v pre-commit &> /dev/null; then
print_yellow "pre-commit not found, attempting to install..."
if command -v pip3 &> /dev/null; then
pip3 install pre-commit
elif command -v pip &> /dev/null; then
pip install pre-commit
else
print_red "pip not found, please install Python and pip first, then run this script again"
exit 1
fi

if [ $? -ne 0 ]; then
print_red "Failed to install pre-commit, please install manually: pip install pre-commit"
exit 1
fi
print_green "pre-commit installed successfully!"
else
print_green "pre-commit is already installed!"
fi
set -euo pipefail

# Check if gitleaks is installed (required)
if ! command -v gitleaks &> /dev/null; then
print_red "❌ gitleaks not found - this is a required security tool!"
print_yellow "Installation guide: https://github.com/gitleaks/gitleaks#installing"

# Attempt automatic installation (based on OS)
if [[ "$OSTYPE" == "darwin"* ]]; then
print_yellow "Detected macOS, attempting to install gitleaks via Homebrew..."
if command -v brew &> /dev/null; then
brew install gitleaks
if [ $? -eq 0 ]; then
print_green "gitleaks installed successfully!"
else
print_red "Cannot automatically install gitleaks, please install manually"
exit 1
fi
else
print_red "Homebrew not found, please install Homebrew or install gitleaks manually"
exit 1
fi
else
print_red "Please install gitleaks manually and try again"
exit 1
fi
else
print_green "gitleaks is installed!"
fi
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# Check required files and directories
if [ ! -d ".git-hooks" ]; then
print_red "Cannot find .git-hooks directory, please ensure you're in the correct project"
if ! repo_root="$(git -C "$script_dir" rev-parse --show-toplevel 2>/dev/null)"; then
echo "Error: .git-hooks must be inside a Git repository." >&2
exit 1
fi

if [ ! -f ".gitleaks.toml" ]; then
print_red "Cannot find .gitleaks.toml configuration file, please ensure it exists"
exit 1
cd "$repo_root"

has_error=false

hooks_path="$(git config --path --get core.hooksPath || true)"

if ! command -v pre-commit >/dev/null 2>&1; then
echo "Error: pre-commit is required. Install it from https://pre-commit.com/#install" >&2
has_error=true
fi

if [ ! -f ".git-hooks/check-commit-message.sh" ]; then
print_red "Cannot find .git-hooks/check-commit-message.sh file, please ensure it exists"
exit 1
if ! command -v gitleaks >/dev/null 2>&1; then
echo "Error: gitleaks is required. Install it from https://github.com/gitleaks/gitleaks#installing" >&2
has_error=true
fi

# Ensure all scripts have executable permissions
print_yellow "Granting executable permissions to hook scripts..."
ensure_executable ".git-hooks/check-commit-message.sh"
ensure_executable ".git-hooks/post-commit"
ensure_executable ".git-hooks/pre-commit"

# Install pre-commit hook
print_yellow "Installing pre-commit hook..."
pre-commit install
if [ $? -ne 0 ]; then
print_red "Failed to install pre-commit hook!"
exit 1
if ! command -v python3 >/dev/null 2>&1; then
echo "Error: python3 is required to validate commit messages." >&2
has_error=true
fi
print_green "pre-commit hook installed successfully!"

# Install commit-msg hook
print_yellow "Installing commit-msg hook..."
pre-commit install --hook-type commit-msg
if [ $? -ne 0 ]; then
print_red "Failed to install commit-msg hook!"
required_files=(
".pre-commit-config.yaml"
".gitleaks.toml"
".git-hooks/run-gitleaks.sh"
".git-hooks/check-commit-message.sh"
".git-hooks/pre-commit-dispatcher.sh"
)

for required_file in "${required_files[@]}"; do
if [[ ! -f "$required_file" ]]; then
echo "Error: required file not found: $required_file" >&2
has_error=true
fi
done

if [[ "$has_error" == true ]]; then
exit 1
fi
print_green "pre-commit commit-msg hook installed successfully!"

# Copy and set up custom hooks
print_yellow "Setting up custom hooks..."
# Copy commit-msg hook
cp .git-hooks/check-commit-message.sh .git/hooks/commit-msg
chmod +x .git/hooks/commit-msg

# Copy post-commit hook (if exists)
if [ -f ".git-hooks/post-commit" ]; then
cp .git-hooks/post-commit .git/hooks/post-commit
chmod +x .git/hooks/post-commit
fi

# Copy pre-commit hook (if exists)
if [ -f ".git-hooks/pre-commit" ]; then
# Backup pre-commit hook
if [ -f ".git/hooks/pre-commit" ]; then
cp .git/hooks/pre-commit .git/hooks/pre-commit.bak
if [[ -z "$hooks_path" ]]; then
pre-commit install --hook-type pre-commit --hook-type commit-msg
else
if [[ "$hooks_path" == /* ]]; then
hooks_dir="$hooks_path"
else
hooks_dir="$repo_root/$hooks_path"
fi

cp .git-hooks/pre-commit .git/hooks/pre-commit.custom
chmod +x .git/hooks/pre-commit.custom

# Add custom pre-commit to existing hook chain
if [ -f ".git/hooks/pre-commit" ]; then
HOOK_CONTENT=$(cat .git/hooks/pre-commit)
if ! grep -q "pre-commit.custom" .git/hooks/pre-commit; then
echo -e "\n# Run custom pre-commit hook\n.git/hooks/pre-commit.custom || exit 1" >> .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit

dispatcher_source=".git-hooks/pre-commit-dispatcher.sh"
dispatcher_marker="api-examples-pre-commit-dispatcher"

for hook_type in pre-commit commit-msg; do
hook_target="$hooks_dir/$hook_type"
if [[ -e "$hook_target" || -L "$hook_target" ]]; then
if ! grep -Fq "$dispatcher_marker" "$hook_target" 2>/dev/null; then
echo "Error: refusing to replace existing hook: $hook_target" >&2
echo "Make that hook invoke pre-commit, then run this script again." >&2
has_error=true
fi
fi
else
echo -e "#!/bin/bash\n\n# Run custom pre-commit hook\n.git/hooks/pre-commit.custom" > .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
done

if [[ "$has_error" == true ]]; then
exit 1
fi
fi

pre-commit clean && pre-commit install && pre-commit install --hook-type commit-msg
mkdir -p "$hooks_dir"
install -m 0755 "$dispatcher_source" "$hooks_dir/pre-commit"
install -m 0755 "$dispatcher_source" "$hooks_dir/commit-msg"
echo "Installed pre-commit dispatchers in configured hook path: $hooks_dir"
fi

print_green "================================================================"
print_green "🎉 Git hooks setup complete! Your repository now has:"
print_green " - Sensitive information leak detection using gitleaks"
print_green " - Chinese character detection in commit messages"
print_green "================================================================"
echo "Git hooks installed successfully:"
echo " - staged changes are scanned for sensitive information"
echo " - commit messages containing Chinese characters are rejected"
Loading
Loading