Skip to content

Commit a4f19b1

Browse files
docs(sdd): bootstrap SDD foundation for components (#859)
Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent b4f087a commit a4f19b1

17 files changed

Lines changed: 2117 additions & 0 deletions

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,8 @@ reports/
4141
!package.json
4242
!package-lock.json
4343
!src/data/*.json
44+
!.sdd/manifest.json
4445
node_modules/
46+
47+
# SDD temporary skill outputs
48+
.generated/

.sdd/manifest.json

Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
{
2+
"manifest_version": 1,
3+
"repository": {
4+
"name": "webex/components",
5+
"purpose": "Published React component library for embedding Webex-styled meeting, messaging, and people UI with adapter-injected data.",
6+
"category": "cat1-legacy",
7+
"primary_languages": ["javascript"]
8+
},
9+
"topology": "Single-repo",
10+
"commands": {
11+
"install": {
12+
"command": "npx npm-install-peers",
13+
"source_file": "CONTRIBUTING.md"
14+
},
15+
"build": {
16+
"command": "npm run build",
17+
"source_file": "package.json"
18+
},
19+
"test": {
20+
"command": "npm run test",
21+
"source_file": "package.json"
22+
},
23+
"lint": {
24+
"command": "npm run linter",
25+
"source_file": "package.json"
26+
},
27+
"coverage": {
28+
"command": "npm run test:coverage",
29+
"source_file": "package.json"
30+
},
31+
"dev": {
32+
"command": "npm run storybook",
33+
"source_file": "package.json"
34+
}
35+
},
36+
"coverage_status_definitions": {
37+
"specced": ">=80% public surface specced, drift <5% — spec is authoritative",
38+
"partial": "40-80% specced — spec is a hint, cross-check code",
39+
"untracked": "<40% specced — code is the source of truth"
40+
},
41+
"modules": [
42+
{
43+
"path": "src/components/",
44+
"coverage_status": "Specced",
45+
"coverage_evidence": "98% field score assessed 2026-07-27; all 31 barrel exports in Public Surface, hooks, HOCs, internal components, and conventions documented",
46+
"canonical_spec": "src/components/ai-docs/components-spec.md",
47+
"contracts": {
48+
"provides": [
49+
"WebexMeeting, WebexMessaging, and other exported React components",
50+
"withAdapter HOC and WebexDataProvider",
51+
"AdapterContext and meeting hooks"
52+
],
53+
"requires": [
54+
"@webex/component-adapter-interfaces adapter instances",
55+
"react, react-dom, prop-types, rxjs peer dependencies",
56+
"compiled CSS from styles-themes module"
57+
]
58+
},
59+
"last_assessed": "2026-07-23",
60+
"section_profile": {
61+
"has_ui": true,
62+
"crosses_service_boundaries": false,
63+
"enforces_domain_rules": false,
64+
"is_concurrent_async": true,
65+
"owns_persistence": false,
66+
"returns_caller_errors": false,
67+
"has_design_tradeoff": false,
68+
"stateful_transitions": true,
69+
"exposes_wire_protocol": false,
70+
"ui_multi_screen": true,
71+
"large_data_model": false,
72+
"has_tiers": false,
73+
"module_specific_conventions": true,
74+
"published_package": true,
75+
"embedded_in_host": true,
76+
"holds_client_state": true,
77+
"resolved_by": "cursor-agent-session (bootstrap questionnaire)",
78+
"resolved_at": "2026-07-23T12:45:00Z"
79+
}
80+
},
81+
{
82+
"path": "src/adapters/",
83+
"coverage_status": "Specced",
84+
"coverage_evidence": "97% field score assessed 2026-07-23; all domain adapters, meeting controls registry, and conventions documented",
85+
"canonical_spec": "src/adapters/ai-docs/adapters-spec.md",
86+
"contracts": {
87+
"provides": [
88+
"WebexJSONAdapter façade (npm public export via src/index.js)",
89+
"Internal domain JSON adapters composed by façade: meetings, people, rooms, activities, memberships, organizations"
90+
],
91+
"requires": [
92+
"@webex/component-adapter-interfaces",
93+
"rxjs",
94+
"JSON datasource with activities, meetings, memberships, organizations, people, rooms keys"
95+
]
96+
},
97+
"last_assessed": "2026-07-23",
98+
"section_profile": {
99+
"has_ui": false,
100+
"crosses_service_boundaries": false,
101+
"enforces_domain_rules": false,
102+
"is_concurrent_async": true,
103+
"owns_persistence": false,
104+
"returns_caller_errors": true,
105+
"has_design_tradeoff": false,
106+
"stateful_transitions": true,
107+
"exposes_wire_protocol": false,
108+
"ui_multi_screen": false,
109+
"large_data_model": false,
110+
"has_tiers": false,
111+
"module_specific_conventions": false,
112+
"published_package": true,
113+
"embedded_in_host": true,
114+
"holds_client_state": true,
115+
"resolved_by": "cursor-agent-session (bootstrap questionnaire)",
116+
"resolved_at": "2026-07-23T12:45:00Z"
117+
}
118+
},
119+
{
120+
"path": "src/styles/",
121+
"coverage_status": "Specced",
122+
"coverage_evidence": "95% field score assessed 2026-07-23; SCSS registry, themes, fonts, build outputs, and conventions documented",
123+
"canonical_spec": "src/styles/ai-docs/styles-themes-spec.md",
124+
"contracts": {
125+
"provides": [
126+
"dist/css/webex-components.css",
127+
"dist/themes/dark and dist/themes/light assets",
128+
"dist/assets/fonts"
129+
],
130+
"requires": [
131+
"component SCSS partials",
132+
"rollup-plugin-scss and rollup-plugin-copy"
133+
]
134+
},
135+
"last_assessed": "2026-07-23",
136+
"section_profile": {
137+
"has_ui": false,
138+
"crosses_service_boundaries": false,
139+
"enforces_domain_rules": false,
140+
"is_concurrent_async": false,
141+
"owns_persistence": false,
142+
"returns_caller_errors": false,
143+
"has_design_tradeoff": false,
144+
"stateful_transitions": false,
145+
"exposes_wire_protocol": false,
146+
"ui_multi_screen": false,
147+
"large_data_model": false,
148+
"has_tiers": false,
149+
"module_specific_conventions": true,
150+
"published_package": true,
151+
"embedded_in_host": true,
152+
"holds_client_state": false,
153+
"resolved_by": "cursor-agent-session (bootstrap questionnaire)",
154+
"resolved_at": "2026-07-23T12:45:00Z"
155+
}
156+
}
157+
],
158+
"spec_policy": {
159+
"delta_grammar": {
160+
"added": "## ADDED Requirements",
161+
"modified": "## MODIFIED Requirements",
162+
"removed": "## REMOVED Requirements"
163+
},
164+
"require_what_and_why": true,
165+
"require_provenance": true,
166+
"protected_specs": [],
167+
"required_sections_by_change_class": {
168+
"core_always": [
169+
"Intent (WHAT)",
170+
"Rationale (WHY)",
171+
"Scope/Out-of-scope",
172+
"Acceptance criteria",
173+
"Contracts delta"
174+
],
175+
"security_or_contract_or_perf_critical": [
176+
"Data",
177+
"Error Matrix",
178+
"Resilience",
179+
"Observability",
180+
"Operations"
181+
]
182+
}
183+
},
184+
"validation": {
185+
"generator_runtime": "cursor-agent-session",
186+
"generator_model": "composer",
187+
"generator_runtime_source": "host-metadata",
188+
"validator_runtime": "codex-agent-session",
189+
"validator_model": "gpt-5",
190+
"validator_runtime_source": "host-metadata",
191+
"minimum_independence": "different-runtime",
192+
"runtime_fallback_tier": "different-runtime",
193+
"blocking_severities": ["Blocking"],
194+
"generator_run_id": "bootstrap-2026-07-23T124500Z",
195+
"validator_run_id": "validation-2026-07-23T085321Z",
196+
"source_commit": "c0140453d4137b7b78bb5656bd13c3e13215d82b",
197+
"base_ref": "master",
198+
"head_ref": "SDLC_SKILLS_FOR_COMPONENTS",
199+
"status": "pass-with-warnings"
200+
},
201+
"layout": {
202+
"sdd_root": ".sdd",
203+
"docs_root": "ai-docs",
204+
"standing_docs_root": "ai-docs",
205+
"spec_index_path": "ai-docs/SPEC_INDEX.md",
206+
"module_docs_strategy": "source-local",
207+
"module_docs_folder_name": "ai-docs",
208+
"template_roots": {
209+
"canonical": ".sdd/templates",
210+
"extensions": [".sdd/templates/extensions"]
211+
},
212+
"repo_skills_root": ".sdd/skills",
213+
"contracts_strategy": "root-index-module-detail"
214+
},
215+
"tooling": {
216+
"sdlc_skills": {
217+
"source_repo": "git@sqbu-github.cisco.com:WebexDevPlatform/SDLC-Skills.git",
218+
"source_ref": "d5ec17e136514addc76df19760f1f00b05ba9c70",
219+
"install_mode": "copy",
220+
"installed_at": "2026-07-23T12:45:00Z",
221+
"plugins": ["sdd-bootstrap"]
222+
}
223+
},
224+
"coverage_ratchet": {
225+
"enabled": true,
226+
"waivers": []
227+
},
228+
"substrate": {
229+
"source": "repo-standards substrate",
230+
"consumed": [
231+
"ESLint config",
232+
"husky pre-commit/pre-push hooks",
233+
"commitlint",
234+
"CircleCI pipeline",
235+
"Storybook configuration",
236+
"README.md",
237+
"CONTRIBUTING.md",
238+
"CODEOWNERS"
239+
],
240+
"compliance_tier": "baseline"
241+
},
242+
"section_profiles": {
243+
"repo": {
244+
"owns_datastore": false,
245+
"holds_client_state": true,
246+
"components_interact": true,
247+
"domain_data_across_components": true,
248+
"caches_data": false,
249+
"observability_convention": false,
250+
"deploys_to_infra": false,
251+
"shared_base_libs": true,
252+
"is_monorepo": false,
253+
"multi_platform": false,
254+
"published_package": true,
255+
"embedded_in_host": true,
256+
"cross_repo_deps_material": true,
257+
"security_arch_warranted": false
258+
},
259+
"resolved_by": "cursor-agent-session (bootstrap questionnaire)",
260+
"resolved_at": "2026-07-23T12:45:00Z"
261+
},
262+
"bootstrap": {
263+
"branch": "SDLC_SKILLS_FOR_COMPONENTS",
264+
"jira": null,
265+
"spec_source_policy_applied": false,
266+
"spec_source_policy_skip_reason": "No existing intent/design specs or AI docs; README and per-component READMEs are reference-only"
267+
}
268+
}

AGENTS.md

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<!-- ───────────────────────────────
2+
Template: AGENTS.md
3+
Template-ID: agents
4+
Generates: AGENTS.md
5+
Description: Agent entry contract — first file every AI agent reads (commands, rules, boundaries, routing).
6+
Library ver: 0.2.1
7+
Last updated: 2026-07-27
8+
─────────────────────────────── -->
9+
10+
# AGENTS.md — webex/components
11+
12+
> 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.
13+
14+
**@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.
15+
16+
**What it is:**
17+
- React 18 UI components (meetings, messaging, roster, settings, auth flows)
18+
- JSON adapters implementing Webex adapter interfaces for offline/demo use
19+
- Rollup-built npm package with SCSS themes and bundled CSS
20+
21+
**What it is NOT:**
22+
- ❌ A full Webex client or SDK — it does not call Webex cloud APIs directly
23+
- ❌ Webex Widgets — widgets bundle the SDK adapter; this library expects hosts to supply adapters
24+
- ❌ A backend service — no server, datastore, or deployment target in this repo
25+
26+
## Tech Stack
27+
28+
- JavaScript (ES modules), React 18.3.1, PropTypes, RxJS 6
29+
- Build: Rollup, Babel, SCSS (`rollup-plugin-scss`)
30+
- Test: Jest, React Testing Library, Storybook 6, Chromatic
31+
- Peer deps: `react`, `react-dom`, `prop-types`, `rxjs`, `@babel/runtime`
32+
33+
## Architecture
34+
35+
```
36+
Host App
37+
└─ withAdapter(Component, adapterFactory) or WebexDataProvider
38+
└─ AdapterContext (meetings, people, rooms, …)
39+
└─ Webex* React components (hooks read adapter observables)
40+
```
41+
42+
→ Full repo architecture: **[ARCHITECTURE.md](./ai-docs/ARCHITECTURE.md)**
43+
44+
## Module / Package Structure
45+
46+
```
47+
src/
48+
├── components/ # Exported + internal React components, hooks, HOCs
49+
├── adapters/ # WebexJSONAdapter + domain JSON adapters
50+
├── styles/ # Global SCSS variables, mixins, defaults
51+
├── themes/ # dark/light theme tokens + assets
52+
├── assets/ # Fonts copied to dist on build
53+
├── constants.js # Class prefix and shared string constants
54+
└── util.js # Shared helpers (deepMerge, rxjs chainWith, …)
55+
```
56+
57+
→ Per-module docs: **[ai-docs/SPEC_INDEX.md](./ai-docs/SPEC_INDEX.md)**
58+
59+
## Critical Rules
60+
61+
1. **Code is the source of truth.** Never invent an API, prop, adapter method, or export — read `src/index.js` and barrel files.
62+
2. **Ask before coding.** Present a plan / Spec Summary; wait for confirmation.
63+
3. **Adapter boundary.** Components consume data only via `@webex/component-adapter-interfaces` adapters injected through `WebexDataProvider` or `withAdapter`.
64+
4. **Class prefix.** Use `WEBEX_COMPONENTS_CLASS_PREFIX` (`wxc`) from `src/constants.js` — must stay aligned with `src/styles/_variables.scss`.
65+
5. **Peer dependencies.** Do not bundle `react`, `react-dom`, `prop-types`, or `rxjs` — they are Rollup externals.
66+
6. **Tests required.** Changes must include Jest tests; follow existing snapshot and hook test patterns.
67+
7. **Lint clean.** `npm run linter` must pass; avoid disabling ESLint rules without maintainer approval.
68+
69+
## Essential Commands
70+
71+
| Task | Command |
72+
|---|---|
73+
| Install (with peers) | `npx install-peerdeps @webex/components` (consumers) / `npx npm-install-peers` (dev) |
74+
| Build | `npm run build` |
75+
| Test | `npm run test` |
76+
| Coverage | `npm run test:coverage` |
77+
| Lint | `npm run linter` |
78+
| Dev / Storybook | `npm run storybook` |
79+
80+
## Common Gotchas
81+
82+
- **Styles side effect:** `src/index.js` imports `./styles/index.scss` — consumers must load compiled CSS from `dist/css/webex-components.css` or equivalent.
83+
- **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.
84+
- **JSON adapter datasource shape:** `WebexJSONAdapter` expects top-level keys `activities`, `meetings`, `memberships`, `organizations`, `people`, `rooms`.
85+
- **Semantic release:** Version bumps are automated — do not manually edit version in `package.json` for releases.
86+
87+
## Boundaries
88+
89+
### Always
90+
- Read this file + `ai-docs/SPEC_INDEX.md` before touching code.
91+
- Match existing component folder layout (`ComponentName/ComponentName.jsx`, co-located tests/stories).
92+
- Update the manifest-routed module spec when changing public surface or behavior.
93+
94+
### Ask first
95+
- New npm dependency or peer dependency change.
96+
- New exported component or breaking prop/adapter contract change.
97+
- Changes to Rollup externals or published `files` list.
98+
99+
### Never
100+
- Commit secrets, tokens, or credentials.
101+
- Disable tests or lint to force green CI.
102+
- Overwrite canonical specs without `spec-reconcile` approval.
103+
104+
## Doc Routing
105+
106+
| Need | Load |
107+
|---|---|
108+
| System shape | `ai-docs/ARCHITECTURE.md` |
109+
| Public exports | `ai-docs/CONTRACTS.md` |
110+
| Module work | `<module-path>/ai-docs/<module-name>-spec.md` |
111+
| Setup | `ai-docs/GETTING_STARTED.md` |
112+
| Enforceable rules | `ai-docs/RULES.md` |
113+
| Conventions | `ai-docs/patterns/` |
114+
115+
Machine contract: `.sdd/manifest.json`

0 commit comments

Comments
 (0)