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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,8 @@ reports/
!package.json
!package-lock.json
!src/data/*.json
!.sdd/manifest.json
node_modules/

# SDD temporary skill outputs
.generated/
268 changes: 268 additions & 0 deletions .sdd/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
{
"manifest_version": 1,
"repository": {
"name": "webex/components",
"purpose": "Published React component library for embedding Webex-styled meeting, messaging, and people UI with adapter-injected data.",
"category": "cat1-legacy",
"primary_languages": ["javascript"]
},
"topology": "Single-repo",
"commands": {
"install": {
"command": "npx npm-install-peers",
"source_file": "CONTRIBUTING.md"
},
"build": {
"command": "npm run build",
"source_file": "package.json"
},
"test": {
"command": "npm run test",
"source_file": "package.json"
},
"lint": {
"command": "npm run linter",
"source_file": "package.json"
},
"coverage": {
"command": "npm run test:coverage",
"source_file": "package.json"
},
"dev": {
"command": "npm run storybook",
"source_file": "package.json"
}
},
"coverage_status_definitions": {
"specced": ">=80% public surface specced, drift <5% — spec is authoritative",
"partial": "40-80% specced — spec is a hint, cross-check code",
"untracked": "<40% specced — code is the source of truth"
},
"modules": [
{
"path": "src/components/",
"coverage_status": "Specced",
"coverage_evidence": "98% field score assessed 2026-07-27; all 31 barrel exports in Public Surface, hooks, HOCs, internal components, and conventions documented",
"canonical_spec": "src/components/ai-docs/components-spec.md",
"contracts": {
"provides": [
"WebexMeeting, WebexMessaging, and other exported React components",
"withAdapter HOC and WebexDataProvider",
"AdapterContext and meeting hooks"
],
"requires": [
"@webex/component-adapter-interfaces adapter instances",
"react, react-dom, prop-types, rxjs peer dependencies",
"compiled CSS from styles-themes module"
]
},
"last_assessed": "2026-07-23",
"section_profile": {
"has_ui": true,
"crosses_service_boundaries": false,
"enforces_domain_rules": false,
"is_concurrent_async": true,
"owns_persistence": false,
"returns_caller_errors": false,
"has_design_tradeoff": false,
"stateful_transitions": true,
"exposes_wire_protocol": false,
"ui_multi_screen": true,
"large_data_model": false,
"has_tiers": false,
"module_specific_conventions": true,
"published_package": true,
"embedded_in_host": true,
"holds_client_state": true,
"resolved_by": "cursor-agent-session (bootstrap questionnaire)",
"resolved_at": "2026-07-23T12:45:00Z"
}
},
{
"path": "src/adapters/",
"coverage_status": "Specced",
"coverage_evidence": "97% field score assessed 2026-07-23; all domain adapters, meeting controls registry, and conventions documented",
"canonical_spec": "src/adapters/ai-docs/adapters-spec.md",
"contracts": {
"provides": [
"WebexJSONAdapter façade (npm public export via src/index.js)",
"Internal domain JSON adapters composed by façade: meetings, people, rooms, activities, memberships, organizations"
],
"requires": [
"@webex/component-adapter-interfaces",
"rxjs",
"JSON datasource with activities, meetings, memberships, organizations, people, rooms keys"
]
},
"last_assessed": "2026-07-23",
"section_profile": {
"has_ui": false,
"crosses_service_boundaries": false,
"enforces_domain_rules": false,
"is_concurrent_async": true,
"owns_persistence": false,
"returns_caller_errors": true,
"has_design_tradeoff": false,
"stateful_transitions": true,
"exposes_wire_protocol": false,
"ui_multi_screen": false,
"large_data_model": false,
"has_tiers": false,
"module_specific_conventions": false,
"published_package": true,
"embedded_in_host": true,
"holds_client_state": true,
"resolved_by": "cursor-agent-session (bootstrap questionnaire)",
"resolved_at": "2026-07-23T12:45:00Z"
}
},
{
"path": "src/styles/",
"coverage_status": "Specced",
"coverage_evidence": "95% field score assessed 2026-07-23; SCSS registry, themes, fonts, build outputs, and conventions documented",
"canonical_spec": "src/styles/ai-docs/styles-themes-spec.md",
"contracts": {
"provides": [
"dist/css/webex-components.css",
"dist/themes/dark and dist/themes/light assets",
"dist/assets/fonts"
],
"requires": [
"component SCSS partials",
"rollup-plugin-scss and rollup-plugin-copy"
]
},
"last_assessed": "2026-07-23",
"section_profile": {
"has_ui": false,
"crosses_service_boundaries": false,
"enforces_domain_rules": false,
"is_concurrent_async": false,
"owns_persistence": false,
"returns_caller_errors": false,
"has_design_tradeoff": false,
"stateful_transitions": false,
"exposes_wire_protocol": false,
"ui_multi_screen": false,
"large_data_model": false,
"has_tiers": false,
"module_specific_conventions": true,
"published_package": true,
"embedded_in_host": true,
"holds_client_state": false,
"resolved_by": "cursor-agent-session (bootstrap questionnaire)",
"resolved_at": "2026-07-23T12:45:00Z"
}
}
],
"spec_policy": {
"delta_grammar": {
"added": "## ADDED Requirements",
"modified": "## MODIFIED Requirements",
"removed": "## REMOVED Requirements"
},
"require_what_and_why": true,
"require_provenance": true,
"protected_specs": [],
"required_sections_by_change_class": {
"core_always": [
"Intent (WHAT)",
"Rationale (WHY)",
"Scope/Out-of-scope",
"Acceptance criteria",
"Contracts delta"
],
"security_or_contract_or_perf_critical": [
"Data",
"Error Matrix",
"Resilience",
"Observability",
"Operations"
]
}
},
"validation": {
"generator_runtime": "cursor-agent-session",
"generator_model": "composer",
"generator_runtime_source": "host-metadata",
"validator_runtime": "codex-agent-session",
"validator_model": "gpt-5",
"validator_runtime_source": "host-metadata",
"minimum_independence": "different-runtime",
"runtime_fallback_tier": "different-runtime",
"blocking_severities": ["Blocking"],
"generator_run_id": "bootstrap-2026-07-23T124500Z",
"validator_run_id": "validation-2026-07-23T085321Z",
"source_commit": "c0140453d4137b7b78bb5656bd13c3e13215d82b",
"base_ref": "master",
"head_ref": "SDLC_SKILLS_FOR_COMPONENTS",
"status": "pass-with-warnings"
},
"layout": {
"sdd_root": ".sdd",
"docs_root": "ai-docs",
"standing_docs_root": "ai-docs",
"spec_index_path": "ai-docs/SPEC_INDEX.md",
"module_docs_strategy": "source-local",
"module_docs_folder_name": "ai-docs",
"template_roots": {
"canonical": ".sdd/templates",
"extensions": [".sdd/templates/extensions"]
},
"repo_skills_root": ".sdd/skills",
"contracts_strategy": "root-index-module-detail"
},
"tooling": {
"sdlc_skills": {
"source_repo": "git@sqbu-github.cisco.com:WebexDevPlatform/SDLC-Skills.git",
"source_ref": "d5ec17e136514addc76df19760f1f00b05ba9c70",
"install_mode": "copy",
"installed_at": "2026-07-23T12:45:00Z",
"plugins": ["sdd-bootstrap"]
}
},
"coverage_ratchet": {
"enabled": true,
"waivers": []
},
"substrate": {
"source": "repo-standards substrate",
"consumed": [
"ESLint config",
"husky pre-commit/pre-push hooks",
"commitlint",
"CircleCI pipeline",
"Storybook configuration",
"README.md",
"CONTRIBUTING.md",
"CODEOWNERS"
],
"compliance_tier": "baseline"
},
"section_profiles": {
"repo": {
"owns_datastore": false,
"holds_client_state": true,
"components_interact": true,
"domain_data_across_components": true,
"caches_data": false,
"observability_convention": false,
"deploys_to_infra": false,
"shared_base_libs": true,
"is_monorepo": false,
"multi_platform": false,
"published_package": true,
"embedded_in_host": true,
"cross_repo_deps_material": true,
"security_arch_warranted": false
},
"resolved_by": "cursor-agent-session (bootstrap questionnaire)",
"resolved_at": "2026-07-23T12:45:00Z"
},
"bootstrap": {
"branch": "SDLC_SKILLS_FOR_COMPONENTS",
"jira": null,
"spec_source_policy_applied": false,
"spec_source_policy_skip_reason": "No existing intent/design specs or AI docs; README and per-component READMEs are reference-only"
}
}
115 changes: 115 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<!-- ───────────────────────────────
Template: AGENTS.md
Template-ID: agents
Generates: AGENTS.md
Description: Agent entry contract — first file every AI agent reads (commands, rules, boundaries, routing).
Library ver: 0.2.1
Last updated: 2026-07-27
─────────────────────────────── -->

# AGENTS.md — webex/components

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These generated docs are missing the hidden template metadata block (Template, Template-ID, Generates, library version, and last updated). The template library explicitly says to preserve that block, and it is absent from all 15 generated Markdown files. Could we restore it across the generated docs so their provenance stays traceable?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 11c6ca9 — restored the hidden template metadata block (Template, Template-ID, Generates, library version, last updated) on all 15 generated Markdown files.


> You are the agent entry point — read first. Next: router [`SPEC_INDEX.md`](ai-docs/SPEC_INDEX.md) · system [`ARCHITECTURE.md`](ai-docs/ARCHITECTURE.md). Load this + `SPEC_INDEX.md` first; pull module/standing docs on demand.

**@webex/components** is a published React component library that embeds Webex-styled meeting, messaging, and people UI into host applications. Data flows through adapter interfaces from `@webex/component-adapter-interfaces`; this repo ships JSON mock adapters for Storybook and local development.

**What it is:**
- React 18 UI components (meetings, messaging, roster, settings, auth flows)
- JSON adapters implementing Webex adapter interfaces for offline/demo use
- Rollup-built npm package with SCSS themes and bundled CSS

**What it is NOT:**
- ❌ A full Webex client or SDK — it does not call Webex cloud APIs directly
- ❌ Webex Widgets — widgets bundle the SDK adapter; this library expects hosts to supply adapters
- ❌ A backend service — no server, datastore, or deployment target in this repo

## Tech Stack

- JavaScript (ES modules), React 18.3.1, PropTypes, RxJS 6
- Build: Rollup, Babel, SCSS (`rollup-plugin-scss`)
- Test: Jest, React Testing Library, Storybook 6, Chromatic
- Peer deps: `react`, `react-dom`, `prop-types`, `rxjs`, `@babel/runtime`

## Architecture

```
Host App
└─ withAdapter(Component, adapterFactory) or WebexDataProvider
└─ AdapterContext (meetings, people, rooms, …)
└─ Webex* React components (hooks read adapter observables)
```

→ Full repo architecture: **[ARCHITECTURE.md](./ai-docs/ARCHITECTURE.md)**

## Module / Package Structure

```
src/
├── components/ # Exported + internal React components, hooks, HOCs
├── adapters/ # WebexJSONAdapter + domain JSON adapters
├── styles/ # Global SCSS variables, mixins, defaults
├── themes/ # dark/light theme tokens + assets
├── assets/ # Fonts copied to dist on build
├── constants.js # Class prefix and shared string constants
└── util.js # Shared helpers (deepMerge, rxjs chainWith, …)
```

→ Per-module docs: **[ai-docs/SPEC_INDEX.md](./ai-docs/SPEC_INDEX.md)**

## Critical Rules

1. **Code is the source of truth.** Never invent an API, prop, adapter method, or export — read `src/index.js` and barrel files.
2. **Ask before coding.** Present a plan / Spec Summary; wait for confirmation.
3. **Adapter boundary.** Components consume data only via `@webex/component-adapter-interfaces` adapters injected through `WebexDataProvider` or `withAdapter`.
4. **Class prefix.** Use `WEBEX_COMPONENTS_CLASS_PREFIX` (`wxc`) from `src/constants.js` — must stay aligned with `src/styles/_variables.scss`.
5. **Peer dependencies.** Do not bundle `react`, `react-dom`, `prop-types`, or `rxjs` — they are Rollup externals.
6. **Tests required.** Changes must include Jest tests; follow existing snapshot and hook test patterns.
7. **Lint clean.** `npm run linter` must pass; avoid disabling ESLint rules without maintainer approval.

## Essential Commands

| Task | Command |
|---|---|
| Install (with peers) | `npx install-peerdeps @webex/components` (consumers) / `npx npm-install-peers` (dev) |
| Build | `npm run build` |
| Test | `npm run test` |
| Coverage | `npm run test:coverage` |
| Lint | `npm run linter` |
| Dev / Storybook | `npm run storybook` |

## Common Gotchas

- **Styles side effect:** `src/index.js` imports `./styles/index.scss` — consumers must load compiled CSS from `dist/css/webex-components.css` or equivalent.
- **Adapter connect lifecycle:** `withAdapter` renders the wrapped component immediately; while `adapter.connect()` is pending, it returns the component **without** `WebexDataProvider` and passes `adapterConnected={false}`. After connect resolves, it re-renders with `WebexDataProvider` and `adapterConnected={true}`. Do not assume `AdapterContext` is available on first paint.
- **JSON adapter datasource shape:** `WebexJSONAdapter` expects top-level keys `activities`, `meetings`, `memberships`, `organizations`, `people`, `rooms`.
- **Semantic release:** Version bumps are automated — do not manually edit version in `package.json` for releases.

## Boundaries

### Always
- Read this file + `ai-docs/SPEC_INDEX.md` before touching code.
- Match existing component folder layout (`ComponentName/ComponentName.jsx`, co-located tests/stories).
- Update the manifest-routed module spec when changing public surface or behavior.

### Ask first
- New npm dependency or peer dependency change.
- New exported component or breaking prop/adapter contract change.
- Changes to Rollup externals or published `files` list.

### Never
- Commit secrets, tokens, or credentials.
- Disable tests or lint to force green CI.
- Overwrite canonical specs without `spec-reconcile` approval.

## Doc Routing

| Need | Load |
|---|---|
| System shape | `ai-docs/ARCHITECTURE.md` |
| Public exports | `ai-docs/CONTRACTS.md` |
| Module work | `<module-path>/ai-docs/<module-name>-spec.md` |
| Setup | `ai-docs/GETTING_STARTED.md` |
| Enforceable rules | `ai-docs/RULES.md` |
| Conventions | `ai-docs/patterns/` |

Machine contract: `.sdd/manifest.json`
Loading