Skip to content
Open
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
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Read this file first, then navigate to the relevant platform directory.

## Repository Overview

This repository contains sample projects demonstrating Agora RTC Native SDK APIs across five platforms. Each platform is fully independent — do not share source files or dependencies across platforms.
This repository contains sample projects demonstrating Agora RTC Native SDK APIs across four independent platforms. Each platform is self-contained — do not share source files, build scripts, or dependencies across platforms.

| Platform | Language(s) | Directory | SDK |
|----------|-------------|-----------|-----|
Expand Down
2 changes: 1 addition & 1 deletion iOS/APIExample/.agent/skills/review-case/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ AgoraAudioSession.sharedInstance().requestRecordPermission { [weak self] granted

**Check:**
- Entry class inherits `UIViewController`, Main class inherits `BaseViewController`
- Class names follow `<ExampleName>Entry` / `<ExampleName>Main` pattern
- Entry class usually follows `<ExampleName>Entry`; the main controller may be `<ExampleName>Main` or an existing project-specific `*ViewController` name as long as storyboard wiring is correct
- `configs` dictionary used to pass data from Entry to Main (no direct property injection)
- File placed under `Examples/Basic/` or `Examples/Advanced/` matching the MenuItem section
- Storyboard ID of Main scene matches the `controller` field in `MenuItem`
Expand Down
21 changes: 17 additions & 4 deletions iOS/APIExample/.agent/skills/upsert-case/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,30 @@ metadata:
## When to Use

- **Add**: the feature has no existing case in `Examples/Basic/` or `Examples/Advanced/`
- **Modify**: the case already exists — skip Steps 1–3, go directly to Step 4+
- **Modify**: the case already exists — update the existing `.swift` and storyboard first, then check registration and docs

Before adding, search the Case Index in `ARCHITECTURE.md` to confirm the case does not already exist.

## Files to Touch

| Scenario | Files |
|----------|-------|
| Add new case | New folder + `.swift` file + `.storyboard`, `ViewController.swift` (MenuItem), `ARCHITECTURE.md` (Case Index) |
| Modify existing case | Existing `.swift` file(s), optionally `.storyboard`, `ARCHITECTURE.md` (Case Index) |
| Add new case | New folder + `.swift` file + `Base.lproj/<ExampleName>.storyboard`, `ViewController.swift` (MenuItem), `ARCHITECTURE.md` (Case Index) |
| Modify existing case | Existing `.swift` file(s), optionally `Base.lproj/<ExampleName>.storyboard`, `ViewController.swift` if registration/wiring changed, `ARCHITECTURE.md` (Case Index) |

---

## Modify Existing Case

When repairing or rebuilding an existing case, use this order instead of the new-case flow:

1. Locate the existing `.swift` implementation and update the actual runtime logic first
2. Update the existing storyboard if scene wiring, outlets, actions, or controller identifiers changed
3. Check `APIExample/ViewController.swift` and fix the `MenuItem` only if registration or `controller` / `storyboard` wiring is wrong
4. Update `ARCHITECTURE.md` last if the case path, APIs, or description changed

Do not skip implementation edits just because the case folder already exists.

## Step 1 — Create the Example Folder

```
Expand Down Expand Up @@ -98,7 +109,7 @@ extension <ExampleName>Main: AgoraRtcEngineDelegate {

## Step 3 — Create the Storyboard

Create `APIExample/Base.lproj/<ExampleName>.storyboard` with two scenes:
Create `APIExample/Examples/[Basic|Advanced]/<ExampleName>/Base.lproj/<ExampleName>.storyboard` with two scenes:

| Scene | Storyboard ID | Class |
|-------|--------------|-------|
Expand All @@ -107,6 +118,8 @@ Create `APIExample/Base.lproj/<ExampleName>.storyboard` with two scenes:

Connect a `Show` segue or use the manual push in `onJoinPressed`.

Keep the storyboard inside the example folder. Do not place new case storyboards in the shared `APIExample/Base.lproj/` directory.

## Default Entry UI Convention

Unless the user explicitly asks for a different flow, use this default Entry layout and interaction:
Expand Down
194 changes: 0 additions & 194 deletions iOS/APIExample/APIExample/Examples/Basic/JoinChannelVideo/SKILL.md

This file was deleted.

3 changes: 2 additions & 1 deletion macOS/.agent/skills/review-case/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ See `references/incorrect-thread-safety.swift` for common mistakes.
- [ ] Microphone permission requested before `enableAudio()`
- [ ] Camera permission requested before `enableVideo()`
- [ ] Permissions checked before accessing devices
- [ ] Review guidance stays macOS-specific and does not suggest iOS-only APIs such as `AVAudioSession.sharedInstance().requestRecordPermission`

**Correct Pattern:**
```swift
Expand All @@ -98,7 +99,7 @@ func initializeAgoraEngine() {
}
}

AVAudioSession.sharedInstance().requestRecordPermission { granted in
AVCaptureDevice.requestAccess(for: .audio) { granted in
if granted {
self.agoraKit.enableAudio()
}
Expand Down
43 changes: 29 additions & 14 deletions macOS/.agent/skills/upsert-case/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name: upsert-case
description: >
Add a new API example or modify an existing one. Covers both creation and modification scenarios,
including file structure, registration, and ARCHITECTURE.md updates.
including file structure, per-example storyboard creation, registration, and ARCHITECTURE.md updates.
compatibility: [Cursor, Kiro, Windsurf, Claude, Copilot]
license: MIT
metadata:
Expand Down Expand Up @@ -30,9 +30,10 @@ Use this skill when you need to:
1. Determine if the example belongs in `Basic/` or `Advanced/`
2. Create the example folder with PascalCase name
3. Create the Swift implementation file
4. Register the example in `ViewController.swift`
5. Update `ARCHITECTURE.md` Case Index
6. Verify compilation and functionality
4. Create the example storyboard
5. Register the example in `ViewController.swift`
6. Update `ARCHITECTURE.md` Case Index
7. Verify compilation and functionality

### Scenario 2: Modify an Existing Example

Expand All @@ -41,8 +42,9 @@ Use this skill when you need to:
**Steps:**
1. Locate the example in `APIExample/Examples/[Basic|Advanced]/<ExampleName>/`
2. Modify the Swift file
3. Update `ARCHITECTURE.md` Case Index if APIs changed
4. Verify compilation and functionality
3. Modify the storyboard if outlets, actions, or controller identifiers changed
4. Update `ARCHITECTURE.md` Case Index if APIs changed
5. Verify compilation and functionality

---

Expand All @@ -53,6 +55,7 @@ Use this skill when you need to:
| File | Action | Notes |
|------|--------|-------|
| `APIExample/Examples/[Basic\|Advanced]/<ExampleName>/<ExampleName>.swift` | Create | Main implementation file |
| `APIExample/Examples/[Basic\|Advanced]/<ExampleName>/Base.lproj/<ExampleName>.storyboard` | Create | Example UI and controller identifier |
| `APIExample/ViewController.swift` | Modify | Register example in menu/list |
| `ARCHITECTURE.md` | Modify | Add entry to Case Index |

Expand All @@ -61,6 +64,7 @@ Use this skill when you need to:
| File | Action | Notes |
|------|--------|-------|
| `APIExample/Examples/[Basic\|Advanced]/<ExampleName>/<ExampleName>.swift` | Modify | Update implementation |
| `APIExample/Examples/[Basic\|Advanced]/<ExampleName>/Base.lproj/<ExampleName>.storyboard` | Modify if needed | Keep outlets and controller identifiers aligned |
| `ARCHITECTURE.md` | Modify | Update Case Index if APIs changed |

---
Expand All @@ -86,19 +90,26 @@ Create `APIExample/Examples/[Basic|Advanced]/<ExampleName>/<ExampleName>.swift`

Use the template from `references/example-template.swift` as a starting point. Replace `<ExampleName>` with your example name.

### Step 4: Register in ViewController
### Step 4: Create the Example Storyboard

Create `APIExample/Examples/[Basic|Advanced]/<ExampleName>/Base.lproj/<ExampleName>.storyboard`.

The storyboard name must match the value passed to `NSStoryboard(name:bundle:)` from `ViewController.swift`, and the main controller identifier in the storyboard must match the `controller` field in `MenuItem`.

### Step 5: Register in ViewController

Edit `APIExample/ViewController.swift` and add the example to the menu/list:

```swift
// In the example list or menu setup
let examples = [
// ... existing examples
("ExampleName", <ExampleName>Main.self),
]
MenuItem(name: "Example Name".localized,
identifier: "menuCell",
controller: "<ExampleName>",
storyboard: "<ExampleName>")
```

### Step 5: Update ARCHITECTURE.md
Place it in the correct section (Basic / Advanced).

### Step 6: Update ARCHITECTURE.md

Add a new row to the Case Index table in `ARCHITECTURE.md`:

Expand All @@ -108,13 +119,14 @@ Add a new row to the Case Index table in `ARCHITECTURE.md`:

**Key APIs column:** List 2-5 core SDK methods used in this example.

### Step 6: Verify
### Step 7: Verify

- [ ] Code compiles without errors
- [ ] Example appears in the menu/list
- [ ] Example can join channel and receive callbacks
- [ ] `leaveChannel()` and `destroy()` are called on close
- [ ] UI updates happen on main thread
- [ ] Storyboard loads with the expected controller identifier
- [ ] ARCHITECTURE.md Case Index is updated

---
Expand All @@ -139,6 +151,7 @@ See `references/` directory for code patterns:
- Forget to implement `AgoraRtcEngineDelegate` for event handling
- Leave the channel without calling `leaveChannel()` first
- Modify examples outside the `APIExample/Examples/[Basic|Advanced]/` structure
- Register a new menu item without also creating the per-example storyboard under the same example folder
- Forget to update `ARCHITECTURE.md` Case Index after adding/modifying an example

---
Expand All @@ -150,6 +163,8 @@ After completing the upsert, verify:
- [ ] Example folder is in correct location (`APIExample/Examples/[Basic|Advanced]/<ExampleName>/`)
- [ ] Swift file is named `<ExampleName>.swift` (PascalCase)
- [ ] Class name is `<ExampleName>Main` and extends `BaseViewController`
- [ ] Storyboard exists at `APIExample/Examples/[Basic|Advanced]/<ExampleName>/Base.lproj/<ExampleName>.storyboard`
- [ ] Storyboard identifier matches the `controller` value registered in `ViewController.swift`
- [ ] Example is registered in `ViewController.swift`
- [ ] `initializeAgoraEngine()` creates engine with correct config
- [ ] `joinChannel()` uses token from `KeyCenter`
Expand Down
Loading
Loading