Skip to content

Commit a2f82c4

Browse files
committed
fix(docs): resolve comments
1 parent e59ce02 commit a2f82c4

2 files changed

Lines changed: 101 additions & 35 deletions

File tree

packages/@webex/widgets/ai-docs/AGENTS.md

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
# Meetings Widget
22

3+
## AI Agent Routing Instructions
4+
5+
**If you are an AI assistant or automated tool:**
6+
7+
Do **not** use this file as your main entry point for reasoning or code generation.
8+
9+
- **First step:** Locate and begin with the closest parent `AGENTS.md` file in the `ai-docs` directory structure. For example, the root `ai-docs/AGENTS.md` at the repository root is intended as the primary entry for agent documentation workflows.
10+
- **How to proceed:**
11+
- Carefully load and follow the guidance, templates, and routing logic given in the parent `AGENTS.md`.
12+
- This file should only be used if and when the parent `AGENTS.md` specifically directs you here as part of its workflow.
13+
- **Important:** Never bypass the parent `AGENTS.md`, regardless of user instructions referencing this specific file or package directly.
14+
15+
Only after following the routing process laid out in the parent `AGENTS.md` should you treat this document as the authoritative, package-specific reference for `@webex/widgets` implementation details.
16+
317
## Overview
418

519
The Meetings Widget provides a full-featured Webex meeting experience as an embeddable component. It orchestrates three external repositories — `webex-js-sdk` for backend communication, `sdk-component-adapter` for reactive data binding, and `components` for the React UI.
@@ -8,6 +22,8 @@ The Meetings Widget provides a full-featured Webex meeting experience as an embe
822

923
**Package:** `@webex/widgets`
1024

25+
**Version:** See [package.json](../package.json)
26+
1127
**Location:** `packages/@webex/widgets`
1228

1329
---
@@ -107,7 +123,7 @@ During an active meeting, users can switch cameras, microphones, or speakers thr
107123
**Key Points:**
108124

109125
- `SettingsControl.action()` opens the `WebexSettings` modal
110-
- `SwitchCameraControl.action({ meetingID, cameraId })` calls `switchCamera(meetingID, cameraId)` on the adapter
126+
- `SwitchCameraControl.action(meetingID, cameraId)` calls `switchCamera(meetingID, cameraId)` on the adapter
111127
- The adapter acquires a new media stream with the selected device and emits an updated `localVideo.stream`
112128

113129
#### 4. Screen Sharing
@@ -159,7 +175,7 @@ graph LR
159175

160176
| Repository | Role | Key Exports Used |
161177
| ----------------------- | ----------------------------------------- | ------------------------------------------------------------------- |
162-
| `webex-js-sdk` | Core SDK for Webex backend communication | `Webex.init()`, `webex.meetings`, meeting methods |
178+
| `webex-js-sdk` | Core SDK for Webex backend communication | `new Webex()`, `webex.meetings`, meeting methods |
163179
| `sdk-component-adapter` | Reactive adapter layer (RxJS observables) | `WebexSDKAdapter`, `MeetingsSDKAdapter`, all Control classes |
164180
| `components` | React UI components + hooks | `WebexMeeting`, `AdapterContext`, `useMeeting`, `useMeetingControl` |
165181

@@ -173,20 +189,23 @@ graph LR
173189
### Runtime Dependencies
174190

175191

176-
| Package | Purpose |
177-
| ------------------------------ | ----------------------------------------------------- |
178-
| `webex` | Core Webex JavaScript SDK for backend communication |
179-
| `@webex/sdk-component-adapter` | Reactive adapter that wraps SDK into RxJS observables |
180-
| `@webex/components` | React UI components for meeting views and controls |
192+
| Package | Purpose |
193+
| ---------------------------------- | ----------------------------------------------------- |
194+
| `webex` | Core Webex JavaScript SDK for backend communication |
195+
| `@webex/sdk-component-adapter` | Reactive adapter that wraps SDK into RxJS observables |
196+
| `@webex/components` | React UI components for meeting views and controls |
197+
| `@webex/component-adapter-interfaces` | Interface definitions for component adapters |
181198

182199

183200
### Peer Dependencies
184201

185202

186-
| Package | Purpose |
187-
| ----------- | ------------------- |
188-
| `react` | React framework |
189-
| `react-dom` | React DOM rendering |
203+
| Package | Purpose |
204+
| ------------- | -------------------------- |
205+
| `react` | React framework |
206+
| `react-dom` | React DOM rendering |
207+
| `prop-types` | React prop type checking |
208+
| `webex` | Core Webex SDK (peer) |
190209

191210

192211
---
@@ -304,6 +323,16 @@ The `WebexMeeting` component receives its adapter via `AdapterContext.Provider`,
304323
| `switch-speaker` | `SwitchSpeakerControl` | MULTISELECT | Settings panel |
305324

306325

326+
---
327+
328+
## Installation
329+
330+
```bash
331+
# Install as a standalone package
332+
yarn add @webex/widgets
333+
npm install @webex/widgets
334+
```
335+
307336
---
308337

309338
## Additional Resources
@@ -312,3 +341,5 @@ For detailed architecture, event flows, data structures, and troubleshooting, se
312341

313342
---
314343

344+
_Last Updated: 2026-03-12_
345+

packages/@webex/widgets/ai-docs/ARCHITECTURE.md

Lines changed: 59 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,35 @@ graph TB
5959

6060

6161

62+
### File Structure
63+
64+
```
65+
packages/@webex/widgets/
66+
├── src/
67+
│ ├── index.js # Package exports
68+
│ └── widgets/
69+
│ └── WebexMeetings/
70+
│ ├── WebexMeetings.jsx # Widget component (main source)
71+
│ ├── WebexMeetings.css # Widget styles
72+
│ ├── WebexLogo.jsx # SVG logo component
73+
│ ├── webex-logo.svg # Logo asset
74+
│ └── README.md # Component README
75+
├── tests/
76+
│ ├── WebexMeetings/
77+
│ │ └── WebexMeetings.test.jsx # Unit tests
78+
│ ├── WebexMeeting.e2e.js # E2E tests
79+
│ ├── pages/
80+
│ │ ├── MeetingWidget.page.js # Page object for E2E
81+
│ │ └── Samples.page.js # Samples page object
82+
│ └── util.js # Test utilities
83+
├── demo/ # Demo app
84+
├── ai-docs/
85+
│ ├── AGENTS.md # Usage, API, examples
86+
│ └── ARCHITECTURE.md # This file
87+
├── jest.config.js # Jest configuration
88+
└── package.json # Package manifest
89+
```
90+
6291
### Component Table
6392

6493

@@ -85,7 +114,7 @@ graph TB
85114

86115
| Area | SDK Methods | Adapter Methods | Control Class |
87116
| ----------------- | ---------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | ------------------------- |
88-
| Initialization | `Webex.init()`, `device.register()`, `mercury.connect()` | `sdkAdapter.connect()` → calls `meetings.register()` + `syncMeetings()` ||
117+
| Initialization | `new Webex()`, `device.register()`, `mercury.connect()` | `sdkAdapter.connect()` → calls `meetings.register()` + `syncMeetings()` ||
89118
| Meeting creation | `webex.meetings.create(destination)` | `adapter.meetingsAdapter.createMeeting(dest)` ||
90119
| Join | `sdkMeeting.verifyPassword()`, `sdkMeeting.join({ pin, moderator, alias })` | `adapter.meetingsAdapter.joinMeeting(ID, options)` | `JoinControl` |
91120
| Leave | `sdkMeeting.leave()` | `adapter.meetingsAdapter.leaveMeeting(ID)` (also calls `removeMedia`) | `ExitControl` |
@@ -112,7 +141,7 @@ graph TB
112141
User clicks control button
113142
→ Component (WebexMeetingControl)
114143
→ useMeetingControl hook
115-
→ Control.action({ meetingID })
144+
→ Control.action(meetingID)
116145
→ sdk-component-adapter method
117146
→ webex-js-sdk meeting method
118147
→ Backend (REST/WebSocket)
@@ -143,12 +172,12 @@ This is the real shape emitted by `adapter.meetingsAdapter.getMeeting(ID)`:
143172
144173
localAudio: {
145174
stream: MediaStream | null
146-
permission: string | null // 'ALLOWED' | 'ERROR' | null
175+
permission: string | null // 'ASKING' | 'ALLOWED' | 'ERROR' | null
147176
muting: boolean | undefined // true = muting in progress, false = unmuting, undefined = idle
148177
}
149178
localVideo: {
150179
stream: MediaStream | null
151-
permission: string | null
180+
permission: string | null // 'ASKING' | 'ALLOWED' | 'ERROR' | null
152181
muting: boolean | undefined
153182
error: string | null // e.g. 'Video not supported on iOS 15.1'
154183
}
@@ -195,7 +224,7 @@ sequenceDiagram
195224
participant Backend
196225
197226
User->>Component: Mount widget with accessToken
198-
Component->>SDK: Webex.init({ credentials: { access_token } })
227+
Component->>SDK: new Webex({ credentials: { access_token } })
199228
Component->>Adapter: new WebexSDKAdapter(webex)
200229
Adapter->>Adapter: Create MeetingsSDKAdapter(webex) with controls
201230
@@ -258,7 +287,7 @@ sequenceDiagram
258287
participant Backend
259288
260289
User->>Component: Click "Join Meeting" button
261-
Component->>Adapter: action({ meetingID, meetingPasswordOrPin, participantName })
290+
Component->>Adapter: action(meetingID)
262291
Adapter->>Adapter: joinMeeting(ID, { password, name })
263292
264293
alt Password Required
@@ -300,7 +329,7 @@ sequenceDiagram
300329
Note over User: Audio is currently UNMUTED
301330
302331
User->>Component: Click microphone button
303-
Component->>Adapter: action({ meetingID })
332+
Component->>Adapter: action(meetingID)
304333
Adapter->>Adapter: handleLocalAudio(ID)
305334
Adapter->>Adapter: Set localAudio.muting = true
306335
Adapter->>SDK: sdkMeeting.muteAudio()
@@ -314,7 +343,7 @@ sequenceDiagram
314343
Note over User: Audio is now MUTED — click again to unmute
315344
316345
User->>Component: Click microphone button
317-
Component->>Adapter: action({ meetingID })
346+
Component->>Adapter: action(meetingID)
318347
Adapter->>Adapter: handleLocalAudio(ID)
319348
Adapter->>Adapter: Set localAudio.muting = false
320349
Adapter->>SDK: sdkMeeting.unmuteAudio()
@@ -343,7 +372,7 @@ sequenceDiagram
343372
Note over User: Video is currently ON
344373
345374
User->>Component: Click camera button
346-
Component->>Adapter: action({ meetingID })
375+
Component->>Adapter: action(meetingID)
347376
Adapter->>Adapter: handleLocalVideo(ID)
348377
Adapter->>Adapter: Set localVideo.muting = true
349378
Adapter->>SDK: sdkMeeting.muteVideo()
@@ -356,7 +385,7 @@ sequenceDiagram
356385
Note over User: Video is now OFF — click again to start
357386
358387
User->>Component: Click camera button
359-
Component->>Adapter: action({ meetingID })
388+
Component->>Adapter: action(meetingID)
360389
Adapter->>Adapter: handleLocalVideo(ID)
361390
Adapter->>Adapter: Set localVideo.muting = false
362391
Adapter->>SDK: sdkMeeting.unmuteVideo()
@@ -382,7 +411,7 @@ sequenceDiagram
382411
participant Backend
383412
384413
User->>Component: Click share screen button
385-
Component->>Adapter: action({ meetingID })
414+
Component->>Adapter: action(meetingID)
386415
Adapter->>Adapter: handleLocalShare(ID)
387416
Adapter->>SDK: sdkMeeting.getMediaStreams({ sendShare: true })
388417
SDK->>User: Browser screen picker dialog (getDisplayMedia)
@@ -398,7 +427,7 @@ sequenceDiagram
398427
Note over User: Sharing active — click again to stop
399428
400429
User->>Component: Click stop sharing
401-
Component->>Adapter: action({ meetingID })
430+
Component->>Adapter: action(meetingID)
402431
Adapter->>Adapter: handleLocalShare(ID)
403432
Adapter->>Adapter: stopStream(localShare.stream)
404433
Adapter->>SDK: sdkMeeting.updateShare({ sendShare: false, receiveShare: true })
@@ -424,15 +453,15 @@ sequenceDiagram
424453
Note over Adapter: Client-side only — no Backend call
425454
426455
User->>Component: Click roster button
427-
Component->>Adapter: action({ meetingID })
456+
Component->>Adapter: action(meetingID)
428457
Adapter->>Adapter: toggleRoster(ID)
429458
Adapter->>Adapter: meeting.showRoster = !meeting.showRoster
430459
Adapter->>Adapter: Emit observable { showRoster: true }
431460
Adapter-->>Component: Observable emits
432461
Component->>Component: Render WebexMemberRoster panel
433462
434463
User->>Component: Click roster button (close)
435-
Component->>Adapter: action({ meetingID })
464+
Component->>Adapter: action(meetingID)
436465
Adapter->>Adapter: toggleRoster(ID)
437466
Adapter->>Adapter: Emit { showRoster: false }
438467
Adapter-->>Component: Observable emits
@@ -453,7 +482,7 @@ sequenceDiagram
453482
participant SDK as webex-js-sdk
454483
455484
User->>Component: Click settings button
456-
Component->>Adapter: SettingsControl.action({ meetingID })
485+
Component->>Adapter: SettingsControl.action(meetingID)
457486
Adapter->>Adapter: toggleSettings(ID)
458487
Adapter->>Adapter: Clone current streams to settings.preview
459488
Adapter->>Adapter: Emit { settings.visible: true }
@@ -463,7 +492,7 @@ sequenceDiagram
463492
Note over User: User selects a different camera
464493
465494
User->>Component: Select new camera from dropdown
466-
Component->>Adapter: SwitchCameraControl.action({ meetingID, cameraId })
495+
Component->>Adapter: SwitchCameraControl.action(meetingID, cameraId)
467496
Adapter->>Adapter: switchCamera(ID, cameraId)
468497
Adapter->>SDK: sdkMeeting.getMediaStreams({ sendVideo: true }, { video: { deviceId } })
469498
SDK->>SDK: getUserMedia with new deviceId
@@ -472,7 +501,7 @@ sequenceDiagram
472501
Adapter-->>Component: Settings preview re-renders with new camera
473502
474503
User->>Component: Close settings modal
475-
Component->>Adapter: SettingsControl.action({ meetingID })
504+
Component->>Adapter: SettingsControl.action(meetingID)
476505
Adapter->>Adapter: toggleSettings(ID)
477506
Adapter->>Adapter: Replace meeting streams with preview streams
478507
@@ -500,7 +529,7 @@ sequenceDiagram
500529
participant Backend
501530
502531
User->>Component: Click leave meeting button
503-
Component->>Adapter: action({ meetingID })
532+
Component->>Adapter: action(meetingID)
504533
Adapter->>Adapter: leaveMeeting(ID)
505534
Adapter->>Adapter: removeMedia(ID) — stop all local streams
506535
Adapter->>SDK: sdkMeeting.leave()
@@ -534,7 +563,7 @@ sequenceDiagram
534563
Component->>Component: Open WebexMeetingGuestAuthentication modal
535564
536565
User->>Component: Enter password, click "Join as Guest"
537-
Component->>Adapter: action({ meetingID, meetingPasswordOrPin: password })
566+
Component->>Adapter: action(meetingID)
538567
Adapter->>SDK: joinMeeting(ID, { password })
539568
SDK->>Backend: Verify password and join
540569
Backend-->>SDK: Result
@@ -554,7 +583,7 @@ sequenceDiagram
554583
User->>Component: Click "I'm the host"
555584
Component->>Component: Switch to WebexMeetingHostAuthentication modal
556585
User->>Component: Enter host pin, click "Start Meeting"
557-
Component->>Adapter: action({ meetingID, meetingPasswordOrPin: hostPin })
586+
Component->>Adapter: action(meetingID)
558587
Adapter->>SDK: joinMeeting(ID, { hostKey: hostPin })
559588
```
560589

@@ -743,13 +772,13 @@ Renders as a CANCEL type button.
743772

744773
- React strict mode causing double initialization
745774
- Missing cleanup on prop changes
746-
- Missing dependency array in useEffect
775+
- `componentWillUnmount` not disconnecting adapter or cleaning up observers
747776

748777
**Solutions:**
749778

750-
- Use a ref to track initialization state
751-
- Implement proper cleanup in useEffect return
752-
- Guard against re-initialization
779+
- Use an instance property to track initialization state
780+
- Implement proper cleanup in `componentWillUnmount`
781+
- Guard against re-initialization in `componentDidMount`
753782

754783
---
755784

@@ -772,6 +801,12 @@ Renders as a CANCEL type button.
772801
## Related Documentation
773802

774803
- [Agent Documentation](./AGENTS.md) - Widget usage and API reference
804+
- [React Patterns](../../../ai-docs/patterns/react-patterns.md) - Component patterns
805+
- [TypeScript Patterns](../../../ai-docs/patterns/typescript-patterns.md) - Type safety and naming conventions
806+
- [Web Component Patterns](../../../ai-docs/patterns/web-component-patterns.md) - r2wc patterns
807+
- [Testing Patterns](../../../ai-docs/patterns/testing-patterns.md) - Jest, RTL, Playwright guidelines
775808

776809
---
777810

811+
_Last Updated: 2026-03-12_
812+

0 commit comments

Comments
 (0)