@webex/internal-plugin-device 3.12.0-next.54 → 3.12.0-next.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.repo-context.json +519 -0
- package/.sdd/manifest.json +335 -0
- package/AGENTS.md +181 -0
- package/dist/device.js +1 -1
- package/dist/ipNetworkDetector.js +1 -1
- package/docs/adr/index.md +28 -0
- package/docs/architecture.md +237 -0
- package/docs/getting-started.md +91 -0
- package/docs/index.md +40 -0
- package/docs/specs/README.md +80 -0
- package/package.json +3 -3
- package/schemas/repo-context.schema.json +796 -0
- package/src/docs/README.md +676 -0
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: Architecture
|
|
3
|
+
title: '@webex/internal-plugin-device architecture'
|
|
4
|
+
description: Boundaries, resources, interactions, dependencies, and cross-cutting architecture of the Webex JS SDK device plugin package.
|
|
5
|
+
tags: [architecture]
|
|
6
|
+
---
|
|
7
|
+
<!-- sdd-generated-metadata
|
|
8
|
+
doc_kind: standing-doc
|
|
9
|
+
generated_from: architecture@0.3.0
|
|
10
|
+
generated_by: claude-code
|
|
11
|
+
approved_by: riag@cisco.com
|
|
12
|
+
updated_at: 2026-10-07T15:08:52Z
|
|
13
|
+
validation_status: pass
|
|
14
|
+
-->
|
|
15
|
+
|
|
16
|
+
# @webex/internal-plugin-device architecture
|
|
17
|
+
|
|
18
|
+
Canonical architecture for the `@webex/internal-plugin-device` package, an internal plugin of the Webex JS SDK
|
|
19
|
+
monorepo. The SDD scope is this package only; the surrounding monorepo is a dependency context, not part of this
|
|
20
|
+
document. Owner-local detail lives in the [module specification](../src/docs/README.md).
|
|
21
|
+
|
|
22
|
+
Related context: [specification registry](specs/README.md) ·
|
|
23
|
+
[repository agent instructions](../AGENTS.md)
|
|
24
|
+
|
|
25
|
+
## Applicability
|
|
26
|
+
|
|
27
|
+
| Condition ID | Status | Evidence or reason | Owned section |
|
|
28
|
+
| ------------------------------------ | ---------- | ------------------------------------------------------------------------------------------------------ | ----------------------------------- |
|
|
29
|
+
| `repo.owns_datastore` | N/A | No store, schema, or migration exists in src/; storage is delegated to @webex/webex-core | Repository data and schema |
|
|
30
|
+
| `repo.holds_client_state` | Applicable | `src/device.js` keeps registration, session, and feature state in memory | Client state model |
|
|
31
|
+
| `repo.components_interact` | Applicable | `src/index.js` wires the plugin, interceptor, and webex.internal collaborators together | Dependency and interaction topology |
|
|
32
|
+
| `repo.domain_data_across_components` | N/A | One writer: `src/device.js` owns the device data; other plugins only read it | Object and data ownership |
|
|
33
|
+
| `repo.caches_data` | Applicable | Persisted device state and the etag-based feature cache in `src/device.js` | Caching catalog |
|
|
34
|
+
| `repo.observability_convention` | Applicable | device:-prefixed logs, internal events, and client metrics in `src/device.js` and `src/metrics.js` | Observability patterns |
|
|
35
|
+
| `repo.deploys_to_infra` | N/A | A library; `package.json` defines no deployment target other than npm publication | Runtime and infrastructure |
|
|
36
|
+
| `repo.shared_base_libs` | N/A | No base library stack is inherited by multiple resources inside this package | Shared and base libraries |
|
|
37
|
+
| `repo.is_monorepo` | N/A | The scoped repository is a single package with one module | Package map and dependencies |
|
|
38
|
+
| `repo.multi_platform` | Applicable | Browser and Node targets: `src/config.js` branches on inBrowser, `package.json` has test:browser | Platform matrix |
|
|
39
|
+
| `repo.published_package` | Applicable | `package.json` declares main and deploy:npm | Release and versioning |
|
|
40
|
+
| `repo.embedded_in_host` | N/A | A plugin of @webex/webex-core, not mounted into a host UI | Host integration and theming |
|
|
41
|
+
| `repo.exposes_commands_or_artifacts` | N/A | No CLI, generator, or stable file output; `package.json` scripts are developer tooling | Commands and generated artifacts |
|
|
42
|
+
| `repo.cross_repo_deps_material` | N/A | All dependencies resolve inside the same workspace or npm | Cross-repository topology |
|
|
43
|
+
| `repo.security_arch_warranted` | N/A | No credential, token, or encryption handling in src/; identity-header rule is covered under Security | Security architecture |
|
|
44
|
+
|
|
45
|
+
## Design overview
|
|
46
|
+
|
|
47
|
+
The package gives every Webex SDK instance one **registered device**: a server-side record at the WDM
|
|
48
|
+
(web device manager) service that other Webex services key on, plus the local state returned with it — device and
|
|
49
|
+
WebSocket URLs, feature toggles, and organization policy. It exists as a separate plugin because dozens of other
|
|
50
|
+
plugins need that registration before they can talk to the backend, but the registration itself is
|
|
51
|
+
independent of messaging, meetings, or calling.
|
|
52
|
+
|
|
53
|
+
Shape: one Ampersand model (`Device`) registered as `webex.internal.device`, owning two children (a
|
|
54
|
+
three-collection feature container and an IP-network detector) and one request interceptor that stamps
|
|
55
|
+
outbound requests with the device URL. Registration is request/response against WDM with three lifecycle
|
|
56
|
+
operations (register, refresh, unregister), a self-healing path for expired registrations (404 on refresh) and
|
|
57
|
+
for the per-user device limit (cleanup then retry). Local policy logic (inactivity logout and intranet
|
|
58
|
+
reachability) hangs off properties delivered in the same payload.
|
|
59
|
+
|
|
60
|
+
Key decisions evidenced in the code: callers need not know registration state because `register()` and `refresh()`
|
|
61
|
+
delegate to each other; concurrent calls share one in-flight request; unknown WDM fields are tolerated so backend
|
|
62
|
+
additions do not break clients; and responses arriving after a logout are discarded. Details are in the module
|
|
63
|
+
specification.
|
|
64
|
+
|
|
65
|
+
## Resource inventory and responsibilities
|
|
66
|
+
|
|
67
|
+
| Resource | Kind | Responsibility | Owner | Source | Detailed specification |
|
|
68
|
+
| ------------------------------ | ------------------------- | --------------------------------------------------------------------------------------------------------------- | -------------------------------------- | ------ | ----------------------- |
|
|
69
|
+
| `@webex/internal-plugin-device` | package (single module `src`) | Device registration lifecycle, device-derived state, `cisco-device-url` header, IP network detection | Webex JS SDK maintainers | src/ | `src/docs/README.md` |
|
|
70
|
+
|
|
71
|
+
## Interaction and execution flows
|
|
72
|
+
|
|
73
|
+
Representative flow: a client authenticates, the device registers, other plugins use the device URL and
|
|
74
|
+
WebSocket URL, and logout unregisters.
|
|
75
|
+
|
|
76
|
+
```mermaid
|
|
77
|
+
flowchart LR
|
|
78
|
+
Auth[Authenticated webex instance] --> Reg[Device.register]
|
|
79
|
+
Reg --> Cat[services catalog: wdm]
|
|
80
|
+
Cat --> WDM[WDM service]
|
|
81
|
+
WDM --> State[Device state and features]
|
|
82
|
+
State --> Event[registration:success]
|
|
83
|
+
Event --> Mercury[Other plugins: websocket url, features]
|
|
84
|
+
State --> Header[DeviceUrlInterceptor adds cisco-device-url]
|
|
85
|
+
Auth -->|logout| Unreg[Device.unregister via onBeforeLogout]
|
|
86
|
+
Unreg --> WDM
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
| From | To | Interaction or transport | Purpose | Failure or compatibility behavior |
|
|
90
|
+
| --------------------- | ------------------------------ | ---------------------------------------------------------------- | ----------------------------------------------- | ---------------------------------------------------------------------------------- |
|
|
91
|
+
| Device | WDM service | HTTP through `webex.request` (POST, PUT, GET, DELETE) | Create, keep, list, and remove registrations | 404 on refresh re-registers; excessive-registration error triggers cleanup and one retry |
|
|
92
|
+
| Device | services plugin | Promise calls for catalog readiness and priority-host mapping | Resolve `wdm` and the WebSocket host | Missing `wdm` rejects registration |
|
|
93
|
+
| DeviceUrlInterceptor | services plugin | `waitForService` and `getServiceFromUrl` on each request | Decide whether to attach the header | Not-found-after-waiting is swallowed; other errors reject the request |
|
|
94
|
+
| Device | metrics plugins | Direct method calls | Time and count registrations | Not guarded in this package |
|
|
95
|
+
| Other plugins | Device | Property reads, events (`registration:success`, `change:features`) | Obtain device URL, WebSocket URL, feature toggles | Property names are relied on across the SDK |
|
|
96
|
+
|
|
97
|
+
## Dependency topology
|
|
98
|
+
|
|
99
|
+
| Dependency | Type | Used by | Purpose | Version, failure, or fallback policy |
|
|
100
|
+
| ----------------------------------- | -------- | ------------------- | ------------------------------------------------------------------------ | -------------------------------------------------------------------------- |
|
|
101
|
+
| `@webex/webex-core` | Internal | Device, helpers | Plugin base, storage decorators, request pipeline, services | Workspace-linked (`workspace:*` in `package.json`); no fallback |
|
|
102
|
+
| `@webex/internal-plugin-metrics` | Internal | Device | Internal events and client metrics | Workspace-linked; imported for its side effects |
|
|
103
|
+
| `@webex/common` | Internal | Device, config | `oneFlight`, `deprecated`, `inBrowser`, `deviceType` | Workspace-linked |
|
|
104
|
+
| `@webex/common-timers` | Internal | Device | `safeSetTimeout` | Workspace-linked |
|
|
105
|
+
| `@webex/http-core` | Internal | Interceptor | `Interceptor` base class | Workspace-linked |
|
|
106
|
+
| `ampersand-state`, `ampersand-collection` | External | Device, features | Model and collection runtime | Pinned by range in `package.json` |
|
|
107
|
+
| `lodash`, `uuid` | External | Device, features, interceptor | Utilities and request-id generation | Pinned by range in `package.json` |
|
|
108
|
+
| WDM service | External | Device | Registration system of record | Reached through the `wdm` catalog entry; no local fallback |
|
|
109
|
+
| Browser `RTCPeerConnection` | External | IP network detector | ICE candidate gathering | Browser only; detection fails elsewhere |
|
|
110
|
+
|
|
111
|
+
No dependency cycle exists inside the package. A runtime cycle exists across packages: the device plugin calls
|
|
112
|
+
the metrics plugin while the metrics plugin is handed the device through `setDeviceInfo`, a method added to avoid a
|
|
113
|
+
circular import (source comment in `@webex/internal-plugin-metrics`). Ordering constraint: `src/index.js` imports the
|
|
114
|
+
metrics plugin before registering the device plugin. Exact versions are in `package.json`.
|
|
115
|
+
|
|
116
|
+
## Public and consumer surfaces
|
|
117
|
+
|
|
118
|
+
Dependency specifications were used where present (`@webex/common`, `@webex/common-timers`, `@webex/http-core`);
|
|
119
|
+
`@webex/webex-core` and `@webex/internal-plugin-metrics` have none, so their source was used.
|
|
120
|
+
|
|
121
|
+
| Surface | Type | Owner | Consumers | Compatibility policy | Source |
|
|
122
|
+
| -------------------------------------------------------------------------------- | ----- | ------------------------------- | -------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | -------------------------------- |
|
|
123
|
+
| `device-plugin-sdk` (npm exports and `webex.internal.device` API) | SDK | `@webex/internal-plugin-device` | SDK plugins, calling and meetings packages, clients | Internal; semantic versioning not strictly followed (README); renames break dependent packages | `package.json` |
|
|
124
|
+
| `device-registration-events` (`registration:success`, `change`, `change:features`, `change:<collection>`) | Event | `@webex/internal-plugin-device` | Plugins listening on the device | Names relied on internally; names are declared in `src/constants.js`, emitted from `src/device.js` and `src/features/features-model.js` | `src/device.js` |
|
|
125
|
+
| `cisco-device-url-header` | API | `@webex/internal-plugin-device` | Webex backend services | Internal; excluded for `idbroker`, `oauth`, `saml` | `src/interceptors/device-url.js` |
|
|
126
|
+
|
|
127
|
+
The contract registry with publication state is `contract_catalog` in `.sdd/manifest.json`; the owning module
|
|
128
|
+
specification, [Public surface](../src/docs/README.md#public-surface), mirrors these entries.
|
|
129
|
+
|
|
130
|
+
## Client state model
|
|
131
|
+
|
|
132
|
+
| State or slice | Owner | Transition triggers | Persistence or reset boundary |
|
|
133
|
+
| ------------------------------- | --------------------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------ |
|
|
134
|
+
| Registration and WDM DTO props | `Device` | register, refresh, unregister, clear | Persisted unless the device is ephemeral; cleared on logout |
|
|
135
|
+
| Feature toggles | `FeaturesModel` collections | Registration responses, debug toggles | Reset by `clear()` |
|
|
136
|
+
| Inactivity and meeting session | `Device` session props | Setting changes, meeting events, user activity | Session only |
|
|
137
|
+
| IP detection results | `IpNetworkDetector` | `detect()` | Reset at the start of each detection |
|
|
138
|
+
|
|
139
|
+
## Cross-cutting architecture
|
|
140
|
+
|
|
141
|
+
### Security
|
|
142
|
+
|
|
143
|
+
- Trust boundaries and identity flow: authentication and tokens are handled by `@webex/webex-core`; this package
|
|
144
|
+
forwards device identity only through the `cisco-device-url` header, which must not reach `idbroker`, `oauth`, or
|
|
145
|
+
`saml` services (`src/interceptors/device-url.js`).
|
|
146
|
+
- Sensitive surfaces and data classes: the device URL and user/organization identifiers stored on the device;
|
|
147
|
+
debug feature toggles are read from `sessionStorage` under a caller-configured key (`src/device.js`).
|
|
148
|
+
- Encryption and secret boundaries: no secrets or cryptography in this package; transport security belongs to the
|
|
149
|
+
request pipeline.
|
|
150
|
+
|
|
151
|
+
### Observability and operations
|
|
152
|
+
|
|
153
|
+
- Logging and correlation: logs go through the plugin logger with a `device:` message prefix; registration
|
|
154
|
+
request and response are timestamped through internal events for call diagnostics (`src/device.js`).
|
|
155
|
+
- Metrics, traces, and audit signals: client metrics for registration success and failure (`src/metrics.js`); no
|
|
156
|
+
traces or audit events.
|
|
157
|
+
- Ownership and operational entry points: no dashboards, alerts, or runbooks are defined in this package.
|
|
158
|
+
|
|
159
|
+
### Quality attributes
|
|
160
|
+
|
|
161
|
+
- Footprint: timers use `safeSetTimeout` so refresh and logout timers do not keep a Node process alive.
|
|
162
|
+
- Compatibility: Node engine floor declared in `package.json`; browser behavior covered by a Karma target and the
|
|
163
|
+
`process` file marks the package as browser-capable.
|
|
164
|
+
- Verification: unit and integration suites under `test/`; no coverage threshold is enforced in this package.
|
|
165
|
+
|
|
166
|
+
## Dependency and interaction topology
|
|
167
|
+
|
|
168
|
+
```mermaid
|
|
169
|
+
flowchart LR
|
|
170
|
+
Index[src/index.js] -->|registerInternalPlugin| Core[webex-core]
|
|
171
|
+
Index -->|interceptors| Interceptor[DeviceUrlInterceptor]
|
|
172
|
+
Index -->|side-effect import| Metrics[internal-plugin-metrics]
|
|
173
|
+
Device[Device] --> Features[FeaturesModel]
|
|
174
|
+
Device --> Detector[IpNetworkDetector]
|
|
175
|
+
Device -->|request| Core
|
|
176
|
+
Device -->|submit| Metrics
|
|
177
|
+
Device -->|safeSetTimeout| Timers[common-timers]
|
|
178
|
+
Device -->|oneFlight, deprecated| Common[common]
|
|
179
|
+
Interceptor -->|extends| Http[http-core Interceptor]
|
|
180
|
+
Device -->|events| Consumers[Other plugins]
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
| From | To | Kind | Purpose | Ordering or failure boundary |
|
|
184
|
+
| -------------------- | ------------------------- | ------ | ----------------------------------------------- | -------------------------------------------------------------------------------- |
|
|
185
|
+
| `src/index.js` | `@webex/webex-core` | Call | Register plugin, interceptor, logout hook | At import time |
|
|
186
|
+
| `src/index.js` | metrics plugin | Import | Make metrics available before registration | Must precede plugin registration |
|
|
187
|
+
| Device | Features, detector | Import | Own child models | Constructed with the device |
|
|
188
|
+
| Device | Other plugins | Event | Announce registration and feature changes | `registration:success` fires after state is stored |
|
|
189
|
+
| Interceptor | Services plugin | Call | Resolve the target service of each request | Waits for the catalog; errors other than not-found reject the request |
|
|
190
|
+
|
|
191
|
+
## Caching catalog
|
|
192
|
+
|
|
193
|
+
| Cache | Owner | Backend | Contents | TTL or bound | Invalidation trigger | Failure behavior |
|
|
194
|
+
| -------------------------- | -------- | ------------------------------- | -------------------------------------------------- | --------------------------------------------- | -------------------------------------------------------- | ----------------------------------------- |
|
|
195
|
+
| Persisted device | `Device` | `@webex/webex-core` bounded storage via `@persist` | Whole device model including `etag` | None in this package | `clear()`; not written at all when ephemeral | Missing storage means a fresh registration |
|
|
196
|
+
| Feature toggle etag cache | `Device` | WDM conditional request (`If-None-Match`) | Developer feature toggles retained across refreshes | Until the etag changes | Etag mismatch, first `change:config` with debug toggles | Mismatch falls back to full response |
|
|
197
|
+
|
|
198
|
+
## Observability patterns
|
|
199
|
+
|
|
200
|
+
| Signal | Convention or required fields | Propagation or naming rule | Primary evidence |
|
|
201
|
+
| ------- | -------------------------------------------------------------------------- | ------------------------------------------------------------ | ---------------------- |
|
|
202
|
+
| Logs | `device: <message>` through `this.logger`; errors logged with the error object | Logger supplied by the webex instance | `src/device.js` |
|
|
203
|
+
| Metrics | `JS_SDK_WDM_REGISTRATION_SUCCESSFUL`, `JS_SDK_WDM_REGISTRATION_FAILED` | Constants exported from one module | `src/metrics.js` |
|
|
204
|
+
| Traces | None | N/A | `src/device.js` |
|
|
205
|
+
| Audit | None | N/A | `src/device.js` |
|
|
206
|
+
|
|
207
|
+
## Platform matrix
|
|
208
|
+
|
|
209
|
+
| Platform | Shared versus platform-specific boundary | Entry or build | Support and compatibility constraints |
|
|
210
|
+
| -------- | ------------------------------------------------------------------------------------------------- | ----------------------------------------- | ------------------------------------------------------------------------------------- |
|
|
211
|
+
| Browser | Same sources; default device name falls back to `browser`; IP network detection works here only | `package.json` scripts `test:browser` | `RTCPeerConnection` required for detection |
|
|
212
|
+
| Node | Same sources; device name defaults to the process title | `package.json` `main` and `test:unit` | Engine floor in `package.json`; no WebRTC, so detection is unavailable |
|
|
213
|
+
|
|
214
|
+
## Release and versioning
|
|
215
|
+
|
|
216
|
+
| Artifact | Publish target | Versioning rule | Deprecation window | Changelog or migration obligation |
|
|
217
|
+
| -------------------------------- | -------------- | -------------------------------------------------------------------- | --------------------------------- | ---------------------------------------------------- |
|
|
218
|
+
| `@webex/internal-plugin-device` | npm (`deploy:npm` script in `package.json`) | Internal plugin; README states semantic versioning is not strictly followed | None defined; deprecation via `@deprecated` decorator | None defined in this package |
|
|
219
|
+
|
|
220
|
+
## Domain language
|
|
221
|
+
|
|
222
|
+
| Term | Repository-specific meaning | Authoritative source |
|
|
223
|
+
| ---------- | ---------------------------------------------------------------------------------------- | ----------------------------------- |
|
|
224
|
+
| WDM | Web device manager: the Webex service that stores device registrations | `src/device.js` |
|
|
225
|
+
| Device | This client's registration at WDM plus its local state, `webex.internal.device` | `src/device.js` |
|
|
226
|
+
| Ephemeral | Registration created with a TTL and refreshed on a timer instead of persisted | `src/config.js` |
|
|
227
|
+
| Feature | A named toggle from WDM in one of `developer`, `entitlement`, `user`, typed on parse | `src/features/feature-model.js` |
|
|
228
|
+
| Catalog | The services catalog that maps service names to hosts; `wdm` must be present | `src/device.js` |
|
|
229
|
+
|
|
230
|
+
## References and maintenance
|
|
231
|
+
|
|
232
|
+
- Decisions: [adr/](adr/index.md)
|
|
233
|
+
- Instantiated specifications and routing: [specs/README.md](specs/README.md)
|
|
234
|
+
- Repository rules and patterns: none approved for this package.
|
|
235
|
+
- Update this document in the same change that alters repository boundaries,
|
|
236
|
+
resource ownership, cross-resource interaction, or cross-cutting
|
|
237
|
+
architecture.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: Getting Started
|
|
3
|
+
title: Getting started
|
|
4
|
+
description: Local setup, build, run, and test routing for @webex/internal-plugin-device.
|
|
5
|
+
tags: [onboarding]
|
|
6
|
+
---
|
|
7
|
+
<!-- sdd-generated-metadata
|
|
8
|
+
doc_kind: standing-doc
|
|
9
|
+
generated_from: getting-started@0.3.0
|
|
10
|
+
generated_by: claude-code
|
|
11
|
+
approved_by: riag@cisco.com
|
|
12
|
+
updated_at: 2026-10-07T15:08:52Z
|
|
13
|
+
validation_status: pass
|
|
14
|
+
-->
|
|
15
|
+
|
|
16
|
+
# Getting started
|
|
17
|
+
|
|
18
|
+
Onboarding for **@webex/internal-plugin-device**, a package inside the Webex JS SDK Yarn workspace. All
|
|
19
|
+
commands below run from the monorepo root through `yarn workspace`.
|
|
20
|
+
|
|
21
|
+
## Prerequisites
|
|
22
|
+
|
|
23
|
+
| Tool or access | Version or requirement |
|
|
24
|
+
| --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
|
|
25
|
+
| Node.js | `>=18` per this package's `engines`; use the version the monorepo root `AGENTS.md` pins for repository work |
|
|
26
|
+
| Yarn workspaces | Provided by the monorepo root; this package declares its workspace dependencies with `workspace:*` |
|
|
27
|
+
| Webex test-user provisioning (integration only) | Required by `@webex/test-helper-test-users`; credentials come from the monorepo's environment setup, not this package |
|
|
28
|
+
|
|
29
|
+
## Install
|
|
30
|
+
|
|
31
|
+
Dependencies are installed once for the whole workspace from the monorepo root (the package defines no install
|
|
32
|
+
script of its own).
|
|
33
|
+
|
|
34
|
+
## Build
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
yarn workspace @webex/internal-plugin-device build:src
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Run
|
|
41
|
+
|
|
42
|
+
This package is a library with no process to start. Consumers import it for its side effect and then use
|
|
43
|
+
`webex.internal.device`, as shown in the package [README](../README.md).
|
|
44
|
+
|
|
45
|
+
## Tests
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
yarn workspace @webex/internal-plugin-device test:unit
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Use the table as the package-level test router. Behavioral intent belongs in the
|
|
52
|
+
[module specification](../src/docs/README.md); exact cases remain in the native test sources.
|
|
53
|
+
|
|
54
|
+
| Tier | Command | Test location | Framework | External dependencies |
|
|
55
|
+
| ----------------------------- | ------------------------------------------------------------- | -------------------- | ---------------------- | -------------------------------------------------------------- |
|
|
56
|
+
| Unit | `yarn workspace @webex/internal-plugin-device test:unit` | `test/unit` | Jest | None |
|
|
57
|
+
| Integration (browser runner) | `yarn workspace @webex/internal-plugin-device test:browser` | `test/integration` | Mocha through Karma | Provisioned Webex test users and network access to Webex services |
|
|
58
|
+
| Style | `yarn workspace @webex/internal-plugin-device test:style` | `src` | ESLint | None |
|
|
59
|
+
|
|
60
|
+
- Coverage or quality gate: none known for this package (owner-confirmed absence of a repo-specific gate).
|
|
61
|
+
- Enforcement source: none.
|
|
62
|
+
- Test environment or QA dependencies: integration specs create real test users; no manual QA tracker is
|
|
63
|
+
recorded.
|
|
64
|
+
|
|
65
|
+
## Configuration and secrets
|
|
66
|
+
|
|
67
|
+
- Required configuration: none for unit tests. Runtime behavior is configured under `webex.config.device`; the
|
|
68
|
+
defaults are in `src/config.js`.
|
|
69
|
+
- Secret source: integration tests obtain credentials through the test-user helper; no secret is stored in this
|
|
70
|
+
package.
|
|
71
|
+
- Package or artifact access: workspace packages resolve locally; publishing uses `yarn workspace @webex/internal-plugin-device deploy:npm`.
|
|
72
|
+
- Required neighboring repositories or workspace layout: this package must stay inside the Webex JS SDK
|
|
73
|
+
workspace so its `workspace:*` dependencies resolve.
|
|
74
|
+
- Platform, simulator, device, or SDK setup: the browser tier needs a browser available to Karma; IP network
|
|
75
|
+
detection needs WebRTC and is not exercised under Node.
|
|
76
|
+
- Never commit credentials or copy production secrets into a local config.
|
|
77
|
+
|
|
78
|
+
## First-run verification
|
|
79
|
+
|
|
80
|
+
1. Run `yarn workspace @webex/internal-plugin-device test:unit`.
|
|
81
|
+
2. Check that every suite reports a pass and no failures.
|
|
82
|
+
3. Run `yarn workspace @webex/internal-plugin-device test:style` for the lint check.
|
|
83
|
+
|
|
84
|
+
Expected result: all six unit suites pass and ESLint reports zero errors (it currently prints warnings, including a
|
|
85
|
+
warning that `src/docs/README.md` is ignored by the lint patterns).
|
|
86
|
+
|
|
87
|
+
## Next steps
|
|
88
|
+
|
|
89
|
+
- [Package architecture](architecture.md)
|
|
90
|
+
- [Specification registry](specs/README.md)
|
|
91
|
+
- [Documentation index](index.md)
|
package/docs/index.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
okf_version: '0.1'
|
|
3
|
+
---
|
|
4
|
+
<!-- sdd-generated-metadata
|
|
5
|
+
doc_kind: standing-doc
|
|
6
|
+
generated_from: docs-index@0.3.0
|
|
7
|
+
generated_by: claude-code
|
|
8
|
+
approved_by: riag@cisco.com
|
|
9
|
+
updated_at: 2026-10-07T15:08:52Z
|
|
10
|
+
validation_status: pass
|
|
11
|
+
-->
|
|
12
|
+
|
|
13
|
+
# @webex/internal-plugin-device documentation
|
|
14
|
+
|
|
15
|
+
Doc map for developers and agents working on the Webex JS SDK device plugin package.
|
|
16
|
+
|
|
17
|
+
## Start here
|
|
18
|
+
|
|
19
|
+
- [Getting started](getting-started.md)
|
|
20
|
+
- [Package architecture](architecture.md)
|
|
21
|
+
|
|
22
|
+
## Decisions
|
|
23
|
+
|
|
24
|
+
- [adr/](adr/index.md) — architectural decision records
|
|
25
|
+
|
|
26
|
+
## Specifications and contracts
|
|
27
|
+
|
|
28
|
+
- [architecture.md](architecture.md) — canonical package architecture and the contract index
|
|
29
|
+
- [specs/README.md](specs/README.md) — manifest-backed module and contract registry
|
|
30
|
+
- [src/docs/README.md](../src/docs/README.md) — the owning specification beside the module's code
|
|
31
|
+
- [adr/](adr/index.md) — concrete architectural decisions; blank ADR templates remain under the repository's `.sdd/` templates
|
|
32
|
+
|
|
33
|
+
No service specification or OpenAPI document exists: this package is a library, not a deployable service, and it
|
|
34
|
+
owns no HTTP contract. The published SDK surface is described by `package.json` and the module's `Public surface`
|
|
35
|
+
section; it is registered in the architecture index rather than copied into Markdown.
|
|
36
|
+
|
|
37
|
+
## Related repository resources
|
|
38
|
+
|
|
39
|
+
The package README ([../README.md](../README.md)) is the original usage guide and remains the consumer-facing
|
|
40
|
+
introduction. No `ci/`, `operate/`, runbook, or diagram folders exist for this package.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: Reference
|
|
3
|
+
title: Specification registry
|
|
4
|
+
description: Canonical specification registry and change-routing guide.
|
|
5
|
+
tags: [specifications, registry]
|
|
6
|
+
---
|
|
7
|
+
<!-- sdd-generated-metadata
|
|
8
|
+
doc_kind: standing-doc
|
|
9
|
+
generated_from: spec-index@0.3.0
|
|
10
|
+
generated_by: claude-code
|
|
11
|
+
approved_by: riag@cisco.com
|
|
12
|
+
updated_at: 2026-10-07T15:08:52Z
|
|
13
|
+
validation_status: pass
|
|
14
|
+
-->
|
|
15
|
+
|
|
16
|
+
# Specification registry
|
|
17
|
+
|
|
18
|
+
Use this page to find the canonical architecture for `@webex/internal-plugin-device` and every instantiated
|
|
19
|
+
module specification plus native contract. Technical facts stay in one owning document; this page is
|
|
20
|
+
navigation, ownership, status, and change/test routing only.
|
|
21
|
+
|
|
22
|
+
Start with the [package architecture](../architecture.md). There is no service specification: the package is a
|
|
23
|
+
published library, not a deployable service.
|
|
24
|
+
|
|
25
|
+
## Document roles
|
|
26
|
+
|
|
27
|
+
| Document | Canonical ownership |
|
|
28
|
+
| ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
|
|
29
|
+
| [Package architecture](../architecture.md) | Package boundaries, resource inventory, interactions, dependency topology, and cross-cutting architecture |
|
|
30
|
+
| Service specification | N/A — not generated; the package has no deployable runtime, so no service or operating contract exists |
|
|
31
|
+
| Module specifications | Stable behavior and design at each module's canonical spec path, routed by `.sdd/manifest.json` |
|
|
32
|
+
| [ADR](../adr/index.md) | A durable decision, its deciders, rationale, consequences, and supersession lineage; none are registered yet |
|
|
33
|
+
|
|
34
|
+
## Instantiated specification registry
|
|
35
|
+
|
|
36
|
+
| Resource | Role | Canonical path | Owner | Status | Last verified |
|
|
37
|
+
| ------------------------------- | ------------ | -------------------------------- | ------------------------ | ------ | ------------- |
|
|
38
|
+
| Repository | Architecture | `docs/architecture.md` | Webex JS SDK maintainers | Draft | 2026-10-07 |
|
|
39
|
+
| `src` | Module | `src/docs/README.md` | Webex JS SDK maintainers | Draft | 2026-10-07 |
|
|
40
|
+
| `device-plugin-sdk` | Contract | `package.json` | Webex JS SDK maintainers | Draft | 2026-10-07 |
|
|
41
|
+
| `device-registration-events` | Contract | `src/device.js` | Webex JS SDK maintainers | Draft | 2026-10-07 |
|
|
42
|
+
| `cisco-device-url-header` | Contract | `src/interceptors/device-url.js` | Webex JS SDK maintainers | Draft | 2026-10-07 |
|
|
43
|
+
|
|
44
|
+
### Module registry
|
|
45
|
+
|
|
46
|
+
One row per module in `.sdd/manifest.json`, which stays authoritative; this table is its
|
|
47
|
+
human-readable mirror and the reconciliation surface for `check_spec_index.py`.
|
|
48
|
+
|
|
49
|
+
| Module | Responsibility | Manifest coverage state | Start here |
|
|
50
|
+
| --- | --- | --- | --- |
|
|
51
|
+
| `src/` | Device registration with the WDM service (register, refresh, unregister, stale-device cleanup), device-derived state and feature toggles, the `cisco-device-url` request header, inactivity logout, and IP network detection | Partial | `src/docs/README.md` |
|
|
52
|
+
|
|
53
|
+
Generator-side field measurement for `src` is complete: 80.0% (12 of 15 mandatory fields) assessed 2026-10-07,
|
|
54
|
+
with critical field coverage at 6 of 7. The score, date, and evidence summary are recorded in the module
|
|
55
|
+
specification's `Coverage score` metadata row and in `.sdd/manifest.json`. Independent validation returned `pass`
|
|
56
|
+
for this documentation set; that is separate from the coverage measurement.
|
|
57
|
+
|
|
58
|
+
Three fields remain weak. The external WDM integration has no committed machine-readable contract and the owner
|
|
59
|
+
has stated none can be provided, so it is recorded as an approved unknown. The design rationale needs owner input
|
|
60
|
+
(no ADR exists). Test and characterization coverage lacks a baseline, and `MOD-015`, `MOD-026`, `INV-004`, and
|
|
61
|
+
`INV-005` have no automated evidence. Promotion to `Specced` stays held while a critical field is weak and no drift
|
|
62
|
+
measurement exists. The improvement decision recorded for this onboarding is `deferred`.
|
|
63
|
+
|
|
64
|
+
## Change and verification routing
|
|
65
|
+
|
|
66
|
+
| Change affects | Load and update | Verification route |
|
|
67
|
+
| ------------------------------------------------------- | --------------------------------------------------------------------------------- | ------------------------------------------------ |
|
|
68
|
+
| Package boundaries or cross-cutting architecture | `docs/architecture.md` and applicable ADRs | Package test routing and affected owner specs |
|
|
69
|
+
| A stable code, package, or component boundary | The module spec `src/docs/README.md` | Module tests plus affected contracts |
|
|
70
|
+
| A public API, event, or header contract | The owning architecture/module section plus the native source named in the registry above | Unit tests and the dependent-package integration suites |
|
|
71
|
+
|
|
72
|
+
## Module and contract registration
|
|
73
|
+
|
|
74
|
+
The module specification is generated at the exact `modules[].canonical_spec` path recorded in
|
|
75
|
+
`.sdd/manifest.json`. Every module and submodule appears in the Module registry above in manifest tree order.
|
|
76
|
+
|
|
77
|
+
Each contract has a stable identity, a `published` or `internal` publication state, a canonical native source,
|
|
78
|
+
and an owning-module link in `contract_catalog`. This package owns no HTTP surface, so no OpenAPI source applies:
|
|
79
|
+
its published SDK surface keeps its ecosystem-native source, `package.json` plus the sources it names. This page
|
|
80
|
+
provides navigation and ownership rather than a copied contract.
|
package/package.json
CHANGED
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
"@webex/common": "3.12.0-next.9",
|
|
40
40
|
"@webex/common-timers": "3.12.0-next.10",
|
|
41
41
|
"@webex/http-core": "3.12.0-next.9",
|
|
42
|
-
"@webex/internal-plugin-metrics": "3.12.0-next.
|
|
43
|
-
"@webex/webex-core": "3.12.0-next.
|
|
42
|
+
"@webex/internal-plugin-metrics": "3.12.0-next.57",
|
|
43
|
+
"@webex/webex-core": "3.12.0-next.61",
|
|
44
44
|
"ampersand-collection": "^2.0.2",
|
|
45
45
|
"ampersand-state": "^5.0.3",
|
|
46
46
|
"lodash": "^4.17.21",
|
|
@@ -55,5 +55,5 @@
|
|
|
55
55
|
"test:style": "eslint ./src/**/*.*",
|
|
56
56
|
"test:unit": "webex-legacy-tools test --unit --runner jest"
|
|
57
57
|
},
|
|
58
|
-
"version": "3.12.0-next.
|
|
58
|
+
"version": "3.12.0-next.56"
|
|
59
59
|
}
|