@generative-a11y/devtools 0.1.1 → 0.2.0
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/README.md +60 -15
- package/dist/index.cjs +31 -4
- package/dist/index.d.cts +8 -6
- package/dist/index.d.ts +8 -6
- package/dist/index.js +30 -3
- package/dist/overlay.cjs +33 -10
- package/dist/overlay.d.cts +6 -6
- package/dist/overlay.d.ts +6 -6
- package/dist/overlay.js +33 -10
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -11,17 +11,17 @@ npm install --save-dev @generative-a11y/devtools
|
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
```ts
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
14
|
+
import { createStore } from "@generative-a11y/devtools";
|
|
15
|
+
import { adapterInfo } from "@generative-a11y/assistant-ui";
|
|
16
16
|
|
|
17
|
-
const store =
|
|
17
|
+
const store = createStore({ maxEntries: 250 });
|
|
18
18
|
const detach = store.attachRuntime({
|
|
19
19
|
id: "support",
|
|
20
20
|
runtime,
|
|
21
21
|
source: {
|
|
22
|
-
adapter:
|
|
23
|
-
fidelity:
|
|
24
|
-
evidence:
|
|
22
|
+
adapter: adapterInfo.name,
|
|
23
|
+
fidelity: adapterInfo.fidelity,
|
|
24
|
+
evidence: adapterInfo.observedRuntimeMethods,
|
|
25
25
|
},
|
|
26
26
|
});
|
|
27
27
|
const unsubscribe = store.subscribe(renderDiagnostics);
|
|
@@ -39,9 +39,9 @@ store.dispose();
|
|
|
39
39
|
|
|
40
40
|
## Store API
|
|
41
41
|
|
|
42
|
-
- `
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
- `createStore({ maxEntries })` creates an isolated store. `maxEntries` defaults
|
|
43
|
+
to `250`, must be a positive safe integer, and bounds the retained ring
|
|
44
|
+
buffer. `droppedCount` reports records evicted since the last `clear()`.
|
|
45
45
|
- `attachRuntime({ id, runtime })` validates a non-empty ID, subscribes only to
|
|
46
46
|
public diagnostics, captures an initial safe snapshot, and returns an
|
|
47
47
|
idempotent detach function. Attaching the same ID replaces its subscription
|
|
@@ -100,15 +100,30 @@ subscribes to a runtime.
|
|
|
100
100
|
## Browser delivery correlation
|
|
101
101
|
|
|
102
102
|
The store intentionally does not import `@generative-a11y/dom`. Connect the
|
|
103
|
-
|
|
103
|
+
active binding's `onDelivery` callback yourself to capture a content-free
|
|
104
104
|
delivery record alongside runtime decisions:
|
|
105
105
|
|
|
106
106
|
```ts
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
import { createRuntime } from "@generative-a11y/core";
|
|
108
|
+
import { bindRuntime } from "@generative-a11y/dom";
|
|
109
|
+
import { createStore } from "@generative-a11y/devtools";
|
|
110
|
+
|
|
111
|
+
export const runtime = createRuntime();
|
|
112
|
+
export const store = createStore();
|
|
113
|
+
const detach = store.attachRuntime({ id: "support", runtime });
|
|
114
|
+
const delivery = bindRuntime(runtime, {
|
|
115
|
+
onDelivery(result) {
|
|
109
116
|
store.recordDelivery({ runtimeId: "support", result });
|
|
110
117
|
},
|
|
111
118
|
});
|
|
119
|
+
|
|
120
|
+
// Dispatch your host events through runtime. Keep this binding for the session.
|
|
121
|
+
export function disposeChat() {
|
|
122
|
+
delivery.dispose();
|
|
123
|
+
detach();
|
|
124
|
+
store.dispose();
|
|
125
|
+
runtime.dispose();
|
|
126
|
+
}
|
|
112
127
|
```
|
|
113
128
|
|
|
114
129
|
This exposes the browser-level method and status (`aria-notify`, fallback live
|
|
@@ -133,12 +148,28 @@ focus. The overlay does not trap focus, create a live region, modify host
|
|
|
133
148
|
layout, or install global shortcuts.
|
|
134
149
|
|
|
135
150
|
```ts
|
|
136
|
-
import {
|
|
151
|
+
import { mountOverlay } from "@generative-a11y/devtools/overlay";
|
|
137
152
|
|
|
138
|
-
const overlay =
|
|
139
|
-
overlay.dispose()
|
|
153
|
+
const overlay = mountOverlay({ store });
|
|
154
|
+
// Call overlay.dispose() when removing the workbench.
|
|
140
155
|
```
|
|
141
156
|
|
|
157
|
+
## Attention decisions
|
|
158
|
+
|
|
159
|
+
When core attention control is enabled, runtime snapshots include the observed
|
|
160
|
+
mode, explicit user override, and effective normal/quiet state. The inspector
|
|
161
|
+
shows these values under policy and scheduling. `attention-updated` explains
|
|
162
|
+
control transitions; `attention-quiet` explains discarded routine output without
|
|
163
|
+
an announcement backlog.
|
|
164
|
+
|
|
165
|
+
`DevtoolsRecord.attentionMode` and `attentionOverride` preserve only recognized
|
|
166
|
+
enum values from control events. Invalid mode payloads are omitted. Exports
|
|
167
|
+
contain no DOM targets or reading history; the observation named
|
|
168
|
+
`reading-history` means only the latest registered response is outside the
|
|
169
|
+
intersection while the document is visible and focused. It does not track a
|
|
170
|
+
screen-reader virtual cursor or prove what someone read. Existing trace schema 1
|
|
171
|
+
consumers can ignore the optional fields.
|
|
172
|
+
|
|
142
173
|
## Documentation
|
|
143
174
|
|
|
144
175
|
- [Devtools guide](https://generativea11y.com/docs/devtools)
|
|
@@ -154,3 +185,17 @@ overlay.dispose();
|
|
|
154
185
|
- [`@generative-a11y/core/testing`](https://generativea11y.com/api/core/testing)
|
|
155
186
|
provides deterministic replay and semantic test assertions without another
|
|
156
187
|
package installation.
|
|
188
|
+
|
|
189
|
+
## Localized announcements
|
|
190
|
+
|
|
191
|
+
Runtime snapshots include optional `messages: { catalogId, locale }`. The
|
|
192
|
+
inspector exposes only these fields and `catalog-format-error`; catalog
|
|
193
|
+
messages, formatter arguments/functions and error text are not retained. Use a
|
|
194
|
+
non-sensitive catalog ID.
|
|
195
|
+
|
|
196
|
+
See the
|
|
197
|
+
[localization guide](https://generativea11y.com/docs/localized-announcements).
|
|
198
|
+
|
|
199
|
+
For React, pass the same callback through
|
|
200
|
+
`<A11yProvider delivery={{ onDelivery }}>`. Do not create another announcer
|
|
201
|
+
beside the provider; its existing delivery path supplies the reports.
|
package/dist/index.cjs
CHANGED
|
@@ -20,7 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
-
|
|
23
|
+
createStore: () => createStore
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(index_exports);
|
|
26
26
|
function asRecord(runtimeId, event, captureSequence, runtimeSourceId) {
|
|
@@ -33,6 +33,14 @@ function asRecord(runtimeId, event, captureSequence, runtimeSourceId) {
|
|
|
33
33
|
at: event.at,
|
|
34
34
|
kind: event.kind,
|
|
35
35
|
sourceType: event.event.type,
|
|
36
|
+
...event.event.type === "attention.changed" && [
|
|
37
|
+
"foreground",
|
|
38
|
+
"background",
|
|
39
|
+
"reading-history",
|
|
40
|
+
"away",
|
|
41
|
+
"unknown"
|
|
42
|
+
].includes(event.event.mode) ? { attentionMode: event.event.mode } : {},
|
|
43
|
+
...event.event.type === "attention.override" && ["auto", "normal", "quiet"].includes(event.event.mode) ? { attentionOverride: event.event.mode } : {},
|
|
36
44
|
...event.event.eventId ? { sourceEventId: event.event.eventId } : {},
|
|
37
45
|
..."runId" in event.event && event.event.runId ? { runId: event.event.runId } : {},
|
|
38
46
|
..."runInstanceId" in event.event && event.event.runInstanceId ? { runInstanceId: event.event.runInstanceId } : {},
|
|
@@ -191,8 +199,27 @@ function copyRuntimeSnapshot(source) {
|
|
|
191
199
|
...source.policy,
|
|
192
200
|
text: Object.freeze({ ...source.policy.text }),
|
|
193
201
|
tools: Object.freeze({ ...source.policy.tools }),
|
|
194
|
-
workflows: Object.freeze({ ...source.policy.workflows })
|
|
202
|
+
workflows: Object.freeze({ ...source.policy.workflows }),
|
|
203
|
+
...source.policy.attention ? {
|
|
204
|
+
attention: Object.freeze({
|
|
205
|
+
...source.policy.attention,
|
|
206
|
+
quietWhen: Object.freeze([...source.policy.attention.quietWhen])
|
|
207
|
+
})
|
|
208
|
+
} : {}
|
|
195
209
|
}),
|
|
210
|
+
...source.messages ? {
|
|
211
|
+
messages: Object.freeze({
|
|
212
|
+
catalogId: source.messages.catalogId,
|
|
213
|
+
locale: source.messages.locale
|
|
214
|
+
})
|
|
215
|
+
} : {},
|
|
216
|
+
...source.attention ? {
|
|
217
|
+
attention: Object.freeze({
|
|
218
|
+
observed: source.attention.observed,
|
|
219
|
+
override: source.attention.override,
|
|
220
|
+
effective: source.attention.effective
|
|
221
|
+
})
|
|
222
|
+
} : {},
|
|
196
223
|
pending: Object.freeze({
|
|
197
224
|
announcements: Object.freeze(
|
|
198
225
|
source.pending.announcements.map((item) => Object.freeze({ ...item }))
|
|
@@ -220,7 +247,7 @@ function copyRuntimeSnapshot(source) {
|
|
|
220
247
|
pendingCount: source.pendingCount
|
|
221
248
|
});
|
|
222
249
|
}
|
|
223
|
-
function
|
|
250
|
+
function createStore(options = {}) {
|
|
224
251
|
const maxEntries = options.maxEntries ?? 250;
|
|
225
252
|
if (!Number.isSafeInteger(maxEntries) || maxEntries <= 0)
|
|
226
253
|
throw new RangeError("maxEntries must be a positive safe integer");
|
|
@@ -427,5 +454,5 @@ function createDevtoolsStore(options = {}) {
|
|
|
427
454
|
}
|
|
428
455
|
// Annotate the CommonJS export names for ESM import in node:
|
|
429
456
|
0 && (module.exports = {
|
|
430
|
-
|
|
457
|
+
createStore
|
|
431
458
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Runtime, AdapterFidelity, AttentionMode, AttentionOverride, RuntimeDiagnosticEventV1, RuntimeDiagnosticSnapshotV1 } from '@generative-a11y/core';
|
|
2
2
|
|
|
3
3
|
type DevtoolsRecordKind = RuntimeDiagnosticEventV1["kind"] | "dom-delivery";
|
|
4
4
|
interface DevtoolsRecord {
|
|
5
|
+
readonly attentionMode?: AttentionMode;
|
|
6
|
+
readonly attentionOverride?: AttentionOverride;
|
|
5
7
|
readonly runtimeId: string;
|
|
6
8
|
/** Opaque key for the immutable adapter evidence captured with this record. */
|
|
7
9
|
readonly runtimeSourceId?: string;
|
|
@@ -113,15 +115,15 @@ interface DevtoolsTraceExportV1 {
|
|
|
113
115
|
readonly runtimeSnapshots: Readonly<Record<string, RuntimeDiagnosticSnapshotV1>>;
|
|
114
116
|
readonly runtimeSources: Readonly<Record<string, DevtoolsRuntimeSource>>;
|
|
115
117
|
}
|
|
116
|
-
interface
|
|
118
|
+
interface StoreOptions {
|
|
117
119
|
readonly maxEntries?: number;
|
|
118
120
|
}
|
|
119
121
|
interface AttachRuntimeOptions {
|
|
120
122
|
readonly id: string;
|
|
121
|
-
readonly runtime: Pick<
|
|
123
|
+
readonly runtime: Pick<Runtime, "subscribeDiagnosticEvents" | "getDiagnosticSnapshot">;
|
|
122
124
|
readonly source?: DevtoolsRuntimeSource;
|
|
123
125
|
}
|
|
124
|
-
interface
|
|
126
|
+
interface Store {
|
|
125
127
|
attachRuntime(options: AttachRuntimeOptions): () => void;
|
|
126
128
|
getSnapshot(): DevtoolsSnapshot;
|
|
127
129
|
subscribe(listener: () => void): () => void;
|
|
@@ -133,6 +135,6 @@ interface DevtoolsStore {
|
|
|
133
135
|
exportTrace(): DevtoolsTraceExportV1;
|
|
134
136
|
dispose(): void;
|
|
135
137
|
}
|
|
136
|
-
declare function
|
|
138
|
+
declare function createStore(options?: StoreOptions): Store;
|
|
137
139
|
|
|
138
|
-
export { type AttachRuntimeOptions, type DeliveryRecordInput, type DevtoolsRecord, type DevtoolsRecordKind, type DevtoolsRuntimeSource, type DevtoolsSnapshot, type
|
|
140
|
+
export { type AttachRuntimeOptions, type DeliveryRecordInput, type DevtoolsRecord, type DevtoolsRecordKind, type DevtoolsRuntimeSource, type DevtoolsSnapshot, type DevtoolsTraceExportV1, type Store, type StoreOptions, createStore };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Runtime, AdapterFidelity, AttentionMode, AttentionOverride, RuntimeDiagnosticEventV1, RuntimeDiagnosticSnapshotV1 } from '@generative-a11y/core';
|
|
2
2
|
|
|
3
3
|
type DevtoolsRecordKind = RuntimeDiagnosticEventV1["kind"] | "dom-delivery";
|
|
4
4
|
interface DevtoolsRecord {
|
|
5
|
+
readonly attentionMode?: AttentionMode;
|
|
6
|
+
readonly attentionOverride?: AttentionOverride;
|
|
5
7
|
readonly runtimeId: string;
|
|
6
8
|
/** Opaque key for the immutable adapter evidence captured with this record. */
|
|
7
9
|
readonly runtimeSourceId?: string;
|
|
@@ -113,15 +115,15 @@ interface DevtoolsTraceExportV1 {
|
|
|
113
115
|
readonly runtimeSnapshots: Readonly<Record<string, RuntimeDiagnosticSnapshotV1>>;
|
|
114
116
|
readonly runtimeSources: Readonly<Record<string, DevtoolsRuntimeSource>>;
|
|
115
117
|
}
|
|
116
|
-
interface
|
|
118
|
+
interface StoreOptions {
|
|
117
119
|
readonly maxEntries?: number;
|
|
118
120
|
}
|
|
119
121
|
interface AttachRuntimeOptions {
|
|
120
122
|
readonly id: string;
|
|
121
|
-
readonly runtime: Pick<
|
|
123
|
+
readonly runtime: Pick<Runtime, "subscribeDiagnosticEvents" | "getDiagnosticSnapshot">;
|
|
122
124
|
readonly source?: DevtoolsRuntimeSource;
|
|
123
125
|
}
|
|
124
|
-
interface
|
|
126
|
+
interface Store {
|
|
125
127
|
attachRuntime(options: AttachRuntimeOptions): () => void;
|
|
126
128
|
getSnapshot(): DevtoolsSnapshot;
|
|
127
129
|
subscribe(listener: () => void): () => void;
|
|
@@ -133,6 +135,6 @@ interface DevtoolsStore {
|
|
|
133
135
|
exportTrace(): DevtoolsTraceExportV1;
|
|
134
136
|
dispose(): void;
|
|
135
137
|
}
|
|
136
|
-
declare function
|
|
138
|
+
declare function createStore(options?: StoreOptions): Store;
|
|
137
139
|
|
|
138
|
-
export { type AttachRuntimeOptions, type DeliveryRecordInput, type DevtoolsRecord, type DevtoolsRecordKind, type DevtoolsRuntimeSource, type DevtoolsSnapshot, type
|
|
140
|
+
export { type AttachRuntimeOptions, type DeliveryRecordInput, type DevtoolsRecord, type DevtoolsRecordKind, type DevtoolsRuntimeSource, type DevtoolsSnapshot, type DevtoolsTraceExportV1, type Store, type StoreOptions, createStore };
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,14 @@ function asRecord(runtimeId, event, captureSequence, runtimeSourceId) {
|
|
|
9
9
|
at: event.at,
|
|
10
10
|
kind: event.kind,
|
|
11
11
|
sourceType: event.event.type,
|
|
12
|
+
...event.event.type === "attention.changed" && [
|
|
13
|
+
"foreground",
|
|
14
|
+
"background",
|
|
15
|
+
"reading-history",
|
|
16
|
+
"away",
|
|
17
|
+
"unknown"
|
|
18
|
+
].includes(event.event.mode) ? { attentionMode: event.event.mode } : {},
|
|
19
|
+
...event.event.type === "attention.override" && ["auto", "normal", "quiet"].includes(event.event.mode) ? { attentionOverride: event.event.mode } : {},
|
|
12
20
|
...event.event.eventId ? { sourceEventId: event.event.eventId } : {},
|
|
13
21
|
..."runId" in event.event && event.event.runId ? { runId: event.event.runId } : {},
|
|
14
22
|
..."runInstanceId" in event.event && event.event.runInstanceId ? { runInstanceId: event.event.runInstanceId } : {},
|
|
@@ -167,8 +175,27 @@ function copyRuntimeSnapshot(source) {
|
|
|
167
175
|
...source.policy,
|
|
168
176
|
text: Object.freeze({ ...source.policy.text }),
|
|
169
177
|
tools: Object.freeze({ ...source.policy.tools }),
|
|
170
|
-
workflows: Object.freeze({ ...source.policy.workflows })
|
|
178
|
+
workflows: Object.freeze({ ...source.policy.workflows }),
|
|
179
|
+
...source.policy.attention ? {
|
|
180
|
+
attention: Object.freeze({
|
|
181
|
+
...source.policy.attention,
|
|
182
|
+
quietWhen: Object.freeze([...source.policy.attention.quietWhen])
|
|
183
|
+
})
|
|
184
|
+
} : {}
|
|
171
185
|
}),
|
|
186
|
+
...source.messages ? {
|
|
187
|
+
messages: Object.freeze({
|
|
188
|
+
catalogId: source.messages.catalogId,
|
|
189
|
+
locale: source.messages.locale
|
|
190
|
+
})
|
|
191
|
+
} : {},
|
|
192
|
+
...source.attention ? {
|
|
193
|
+
attention: Object.freeze({
|
|
194
|
+
observed: source.attention.observed,
|
|
195
|
+
override: source.attention.override,
|
|
196
|
+
effective: source.attention.effective
|
|
197
|
+
})
|
|
198
|
+
} : {},
|
|
172
199
|
pending: Object.freeze({
|
|
173
200
|
announcements: Object.freeze(
|
|
174
201
|
source.pending.announcements.map((item) => Object.freeze({ ...item }))
|
|
@@ -196,7 +223,7 @@ function copyRuntimeSnapshot(source) {
|
|
|
196
223
|
pendingCount: source.pendingCount
|
|
197
224
|
});
|
|
198
225
|
}
|
|
199
|
-
function
|
|
226
|
+
function createStore(options = {}) {
|
|
200
227
|
const maxEntries = options.maxEntries ?? 250;
|
|
201
228
|
if (!Number.isSafeInteger(maxEntries) || maxEntries <= 0)
|
|
202
229
|
throw new RangeError("maxEntries must be a positive safe integer");
|
|
@@ -402,5 +429,5 @@ function createDevtoolsStore(options = {}) {
|
|
|
402
429
|
};
|
|
403
430
|
}
|
|
404
431
|
export {
|
|
405
|
-
|
|
432
|
+
createStore
|
|
406
433
|
};
|
package/dist/overlay.cjs
CHANGED
|
@@ -30,7 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/overlay.ts
|
|
31
31
|
var overlay_exports = {};
|
|
32
32
|
__export(overlay_exports, {
|
|
33
|
-
|
|
33
|
+
mountOverlay: () => mountOverlay
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(overlay_exports);
|
|
36
36
|
var import_react2 = require("react");
|
|
@@ -284,7 +284,7 @@ function relatedRecords(records, selected) {
|
|
|
284
284
|
}
|
|
285
285
|
function explain(record) {
|
|
286
286
|
if (record.kind === "event-observed")
|
|
287
|
-
return "The adapter supplied this normalized public lifecycle signal.";
|
|
287
|
+
return record.sourceType?.startsWith("attention.") ? "The host supplied an attention observation or explicit user override. Browser evidence does not establish what someone is reading." : "The adapter supplied this normalized public lifecycle signal.";
|
|
288
288
|
if (record.kind === "dom-delivery")
|
|
289
289
|
return record.deliveryStatus === "unavailable" ? "The DOM driver was unavailable, so no browser delivery action was observed." : "The DOM driver reported this delivery action.";
|
|
290
290
|
return {
|
|
@@ -292,6 +292,9 @@ function explain(record) {
|
|
|
292
292
|
coalesced: "The runtime merged this work with an existing queued announcement.",
|
|
293
293
|
duplicate: "The runtime suppressed a recently delivered duplicate.",
|
|
294
294
|
"policy-silent": "The active policy intentionally made this event silent.",
|
|
295
|
+
"catalog-format-error": "The host message formatter failed; the runtime used a generic English notice without retaining the error or parameters.",
|
|
296
|
+
"attention-quiet": "Quiet mode discarded routine output without retaining an announcement backlog.",
|
|
297
|
+
"attention-updated": "The runtime updated its attention observation or user override without announcing the control event.",
|
|
295
298
|
"queue-capacity": "The bounded queue rejected or displaced this work.",
|
|
296
299
|
"scope-cancelled": "The lifecycle scope ended before this queued work delivered.",
|
|
297
300
|
"runtime-disposed": "The runtime was disposed and cancelled remaining queued work.",
|
|
@@ -443,6 +446,30 @@ function Detail({
|
|
|
443
446
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("section", { className: "ga-detail-section", children: [
|
|
444
447
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h4", { children: "Policy and scheduling" }),
|
|
445
448
|
runtime ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("dl", { className: "ga-key-values", children: [
|
|
449
|
+
runtime.messages && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
450
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
|
|
451
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dt", { children: "Announcement catalog" }),
|
|
452
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dd", { children: runtime.messages.catalogId })
|
|
453
|
+
] }),
|
|
454
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
|
|
455
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dt", { children: "Notice language" }),
|
|
456
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dd", { children: runtime.messages.locale })
|
|
457
|
+
] })
|
|
458
|
+
] }),
|
|
459
|
+
runtime.attention && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
460
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
|
|
461
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dt", { children: "Effective announcements" }),
|
|
462
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dd", { children: runtime.attention.effective })
|
|
463
|
+
] }),
|
|
464
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
|
|
465
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dt", { children: "Observed attention" }),
|
|
466
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dd", { children: runtime.attention.observed })
|
|
467
|
+
] }),
|
|
468
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
|
|
469
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dt", { children: "User override" }),
|
|
470
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dd", { children: runtime.attention.override })
|
|
471
|
+
] })
|
|
472
|
+
] }),
|
|
446
473
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
|
|
447
474
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dt", { children: "Queue" }),
|
|
448
475
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("dd", { children: [
|
|
@@ -532,11 +559,7 @@ function List({
|
|
|
532
559
|
}
|
|
533
560
|
);
|
|
534
561
|
}
|
|
535
|
-
function
|
|
536
|
-
store,
|
|
537
|
-
onClose,
|
|
538
|
-
onCopy
|
|
539
|
-
}) {
|
|
562
|
+
function Inspector({ store, onClose, onCopy }) {
|
|
540
563
|
const snapshot = useSnapshot(store);
|
|
541
564
|
const reduceMotion = (0, import_react.useReducedMotion)();
|
|
542
565
|
const [query, setQuery] = React4.useState("");
|
|
@@ -842,7 +865,7 @@ button:focus-visible, input:focus-visible, [role="listbox"]:focus-visible, [role
|
|
|
842
865
|
.ga-workspace-feedback { top: 68px; color: #f7f7f7; background: #111; border-color: #111; border-radius: 3px; box-shadow: none; }
|
|
843
866
|
@media (max-width: 760px) { .ga-bottom-dock { height: min(720px, 80vh); } .ga-inspector-header, .ga-session-toolbar { padding-right: 12px; padding-left: 12px; } .ga-session-toolbar { flex-wrap: wrap; } .ga-inspector-search { width: 100%; } .ga-session-count { margin-left: 0; } .ga-explorer-layout { flex-direction: column; } [data-slot="resizable-handle"] { width: 100%; height: 1px; } .ga-trace-row { grid-template-columns: 70px 1fr; padding: 8px 12px; } .ga-trace-row span, .ga-trace-row code { grid-column: 2; } .ga-trace-detail { padding: 18px 12px; } .ga-key-values { grid-template-columns: 1fr; } .ga-key-values-wide { grid-column: auto; } }
|
|
844
867
|
`;
|
|
845
|
-
function
|
|
868
|
+
function mountOverlay(options) {
|
|
846
869
|
const selectedDocument = options.document ?? (typeof document === "undefined" ? void 0 : document);
|
|
847
870
|
if (!selectedDocument?.body)
|
|
848
871
|
throw new Error("A mountable document is required");
|
|
@@ -897,7 +920,7 @@ function mountDevtoolsOverlay(options) {
|
|
|
897
920
|
return clipboard.writeText(value);
|
|
898
921
|
});
|
|
899
922
|
root.render(
|
|
900
|
-
(0, import_react2.createElement)(
|
|
923
|
+
(0, import_react2.createElement)(Inspector, {
|
|
901
924
|
onClose: close,
|
|
902
925
|
onCopy: copyText,
|
|
903
926
|
store: options.store
|
|
@@ -936,5 +959,5 @@ function mountDevtoolsOverlay(options) {
|
|
|
936
959
|
}
|
|
937
960
|
// Annotate the CommonJS export names for ESM import in node:
|
|
938
961
|
0 && (module.exports = {
|
|
939
|
-
|
|
962
|
+
mountOverlay
|
|
940
963
|
});
|
package/dist/overlay.d.cts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Store } from './index.cjs';
|
|
2
2
|
import '@generative-a11y/core';
|
|
3
3
|
|
|
4
|
-
interface
|
|
5
|
-
readonly store:
|
|
4
|
+
interface OverlayOptions {
|
|
5
|
+
readonly store: Store;
|
|
6
6
|
readonly document?: Document;
|
|
7
7
|
readonly copyText?: (value: string) => void | Promise<void>;
|
|
8
8
|
}
|
|
9
|
-
interface
|
|
9
|
+
interface Overlay {
|
|
10
10
|
readonly host: HTMLElement;
|
|
11
11
|
dispose(): void;
|
|
12
12
|
}
|
|
13
|
-
declare function
|
|
13
|
+
declare function mountOverlay(options: OverlayOptions): Overlay;
|
|
14
14
|
|
|
15
|
-
export { type
|
|
15
|
+
export { type Overlay, type OverlayOptions, mountOverlay };
|
package/dist/overlay.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Store } from './index.js';
|
|
2
2
|
import '@generative-a11y/core';
|
|
3
3
|
|
|
4
|
-
interface
|
|
5
|
-
readonly store:
|
|
4
|
+
interface OverlayOptions {
|
|
5
|
+
readonly store: Store;
|
|
6
6
|
readonly document?: Document;
|
|
7
7
|
readonly copyText?: (value: string) => void | Promise<void>;
|
|
8
8
|
}
|
|
9
|
-
interface
|
|
9
|
+
interface Overlay {
|
|
10
10
|
readonly host: HTMLElement;
|
|
11
11
|
dispose(): void;
|
|
12
12
|
}
|
|
13
|
-
declare function
|
|
13
|
+
declare function mountOverlay(options: OverlayOptions): Overlay;
|
|
14
14
|
|
|
15
|
-
export { type
|
|
15
|
+
export { type Overlay, type OverlayOptions, mountOverlay };
|
package/dist/overlay.js
CHANGED
|
@@ -187,7 +187,7 @@ function ScrollBar({
|
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
// src/inspector.tsx
|
|
190
|
-
import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
190
|
+
import { Fragment, jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
191
191
|
var key = (record) => String(record.captureSequence);
|
|
192
192
|
var time = (value) => value >= 1e10 ? new Date(value).toISOString().slice(11, 23) : `+${(value / 1e3).toFixed(2)}s`;
|
|
193
193
|
var stage = (record) => record.kind === "event-observed" ? "Source evidence" : record.kind === "decision" ? "Runtime decision" : "DOM delivery";
|
|
@@ -250,7 +250,7 @@ function relatedRecords(records, selected) {
|
|
|
250
250
|
}
|
|
251
251
|
function explain(record) {
|
|
252
252
|
if (record.kind === "event-observed")
|
|
253
|
-
return "The adapter supplied this normalized public lifecycle signal.";
|
|
253
|
+
return record.sourceType?.startsWith("attention.") ? "The host supplied an attention observation or explicit user override. Browser evidence does not establish what someone is reading." : "The adapter supplied this normalized public lifecycle signal.";
|
|
254
254
|
if (record.kind === "dom-delivery")
|
|
255
255
|
return record.deliveryStatus === "unavailable" ? "The DOM driver was unavailable, so no browser delivery action was observed." : "The DOM driver reported this delivery action.";
|
|
256
256
|
return {
|
|
@@ -258,6 +258,9 @@ function explain(record) {
|
|
|
258
258
|
coalesced: "The runtime merged this work with an existing queued announcement.",
|
|
259
259
|
duplicate: "The runtime suppressed a recently delivered duplicate.",
|
|
260
260
|
"policy-silent": "The active policy intentionally made this event silent.",
|
|
261
|
+
"catalog-format-error": "The host message formatter failed; the runtime used a generic English notice without retaining the error or parameters.",
|
|
262
|
+
"attention-quiet": "Quiet mode discarded routine output without retaining an announcement backlog.",
|
|
263
|
+
"attention-updated": "The runtime updated its attention observation or user override without announcing the control event.",
|
|
261
264
|
"queue-capacity": "The bounded queue rejected or displaced this work.",
|
|
262
265
|
"scope-cancelled": "The lifecycle scope ended before this queued work delivered.",
|
|
263
266
|
"runtime-disposed": "The runtime was disposed and cancelled remaining queued work.",
|
|
@@ -409,6 +412,30 @@ function Detail({
|
|
|
409
412
|
/* @__PURE__ */ jsxs2("section", { className: "ga-detail-section", children: [
|
|
410
413
|
/* @__PURE__ */ jsx5("h4", { children: "Policy and scheduling" }),
|
|
411
414
|
runtime ? /* @__PURE__ */ jsxs2("dl", { className: "ga-key-values", children: [
|
|
415
|
+
runtime.messages && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
416
|
+
/* @__PURE__ */ jsxs2("div", { children: [
|
|
417
|
+
/* @__PURE__ */ jsx5("dt", { children: "Announcement catalog" }),
|
|
418
|
+
/* @__PURE__ */ jsx5("dd", { children: runtime.messages.catalogId })
|
|
419
|
+
] }),
|
|
420
|
+
/* @__PURE__ */ jsxs2("div", { children: [
|
|
421
|
+
/* @__PURE__ */ jsx5("dt", { children: "Notice language" }),
|
|
422
|
+
/* @__PURE__ */ jsx5("dd", { children: runtime.messages.locale })
|
|
423
|
+
] })
|
|
424
|
+
] }),
|
|
425
|
+
runtime.attention && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
426
|
+
/* @__PURE__ */ jsxs2("div", { children: [
|
|
427
|
+
/* @__PURE__ */ jsx5("dt", { children: "Effective announcements" }),
|
|
428
|
+
/* @__PURE__ */ jsx5("dd", { children: runtime.attention.effective })
|
|
429
|
+
] }),
|
|
430
|
+
/* @__PURE__ */ jsxs2("div", { children: [
|
|
431
|
+
/* @__PURE__ */ jsx5("dt", { children: "Observed attention" }),
|
|
432
|
+
/* @__PURE__ */ jsx5("dd", { children: runtime.attention.observed })
|
|
433
|
+
] }),
|
|
434
|
+
/* @__PURE__ */ jsxs2("div", { children: [
|
|
435
|
+
/* @__PURE__ */ jsx5("dt", { children: "User override" }),
|
|
436
|
+
/* @__PURE__ */ jsx5("dd", { children: runtime.attention.override })
|
|
437
|
+
] })
|
|
438
|
+
] }),
|
|
412
439
|
/* @__PURE__ */ jsxs2("div", { children: [
|
|
413
440
|
/* @__PURE__ */ jsx5("dt", { children: "Queue" }),
|
|
414
441
|
/* @__PURE__ */ jsxs2("dd", { children: [
|
|
@@ -498,11 +525,7 @@ function List({
|
|
|
498
525
|
}
|
|
499
526
|
);
|
|
500
527
|
}
|
|
501
|
-
function
|
|
502
|
-
store,
|
|
503
|
-
onClose,
|
|
504
|
-
onCopy
|
|
505
|
-
}) {
|
|
528
|
+
function Inspector({ store, onClose, onCopy }) {
|
|
506
529
|
const snapshot = useSnapshot(store);
|
|
507
530
|
const reduceMotion = useReducedMotion();
|
|
508
531
|
const [query, setQuery] = React4.useState("");
|
|
@@ -808,7 +831,7 @@ button:focus-visible, input:focus-visible, [role="listbox"]:focus-visible, [role
|
|
|
808
831
|
.ga-workspace-feedback { top: 68px; color: #f7f7f7; background: #111; border-color: #111; border-radius: 3px; box-shadow: none; }
|
|
809
832
|
@media (max-width: 760px) { .ga-bottom-dock { height: min(720px, 80vh); } .ga-inspector-header, .ga-session-toolbar { padding-right: 12px; padding-left: 12px; } .ga-session-toolbar { flex-wrap: wrap; } .ga-inspector-search { width: 100%; } .ga-session-count { margin-left: 0; } .ga-explorer-layout { flex-direction: column; } [data-slot="resizable-handle"] { width: 100%; height: 1px; } .ga-trace-row { grid-template-columns: 70px 1fr; padding: 8px 12px; } .ga-trace-row span, .ga-trace-row code { grid-column: 2; } .ga-trace-detail { padding: 18px 12px; } .ga-key-values { grid-template-columns: 1fr; } .ga-key-values-wide { grid-column: auto; } }
|
|
810
833
|
`;
|
|
811
|
-
function
|
|
834
|
+
function mountOverlay(options) {
|
|
812
835
|
const selectedDocument = options.document ?? (typeof document === "undefined" ? void 0 : document);
|
|
813
836
|
if (!selectedDocument?.body)
|
|
814
837
|
throw new Error("A mountable document is required");
|
|
@@ -863,7 +886,7 @@ function mountDevtoolsOverlay(options) {
|
|
|
863
886
|
return clipboard.writeText(value);
|
|
864
887
|
});
|
|
865
888
|
root.render(
|
|
866
|
-
createElement(
|
|
889
|
+
createElement(Inspector, {
|
|
867
890
|
onClose: close,
|
|
868
891
|
onCopy: copyText,
|
|
869
892
|
store: options.store
|
|
@@ -901,5 +924,5 @@ function mountDevtoolsOverlay(options) {
|
|
|
901
924
|
};
|
|
902
925
|
}
|
|
903
926
|
export {
|
|
904
|
-
|
|
927
|
+
mountOverlay
|
|
905
928
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@generative-a11y/devtools",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Development-only accessibility diagnostics and a redacted trace explorer for screen-reader announcements in AI runtimes.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"accessibility",
|
|
@@ -56,11 +56,11 @@
|
|
|
56
56
|
"class-variance-authority": "0.7.1",
|
|
57
57
|
"clsx": "2.1.1",
|
|
58
58
|
"lucide-react": "1.31.0",
|
|
59
|
-
"motion": "^
|
|
59
|
+
"motion": "^13.1.1",
|
|
60
60
|
"radix-ui": "1.6.7",
|
|
61
61
|
"react-resizable-panels": "^4.12.3",
|
|
62
62
|
"tailwind-merge": "3.6.0",
|
|
63
|
-
"@generative-a11y/core": "0.
|
|
63
|
+
"@generative-a11y/core": "0.4.0"
|
|
64
64
|
},
|
|
65
65
|
"peerDependencies": {
|
|
66
66
|
"react": "^19.0.0",
|