@pie-players/pie-assessment-toolkit 0.3.75 → 1.0.0-beta.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.
Files changed (142) hide show
  1. package/README.md +449 -541
  2. package/custom-elements.json +1315 -0
  3. package/dist/attempt/TestSession.d.ts +0 -1
  4. package/dist/attempt/TestSession.js +10 -5
  5. package/dist/components/ItemScope.custom-element.js +1 -1
  6. package/dist/components/ItemToolBar.custom-element.js +1 -1
  7. package/dist/components/PieAssessmentToolkit.custom-element.js +8 -8
  8. package/dist/components/SectionToolBar.custom-element.js +1 -1
  9. package/dist/components/chunks/{ItemToolBar-7tt7v2xp.js → ItemToolBar-3zrc4p3d.js} +4 -4
  10. package/dist/components/chunks/{ItemToolBar-jx38w99s.js → ItemToolBar-66hcwmfw.js} +2 -2
  11. package/dist/components/chunks/ItemToolBar-9gqhfxtn.js +40 -0
  12. package/dist/components/chunks/ItemToolBar-hzc5wyjp.js +2 -0
  13. package/dist/components/chunks/{ItemToolBar-97hx60z4.js → ItemToolBar-kkj69ptr.js} +1 -1
  14. package/dist/components/chunks/sre-engine-bj997w4b.js +1 -0
  15. package/dist/context/assessment-toolkit-context.d.ts +6 -0
  16. package/dist/index.d.ts +7 -7
  17. package/dist/index.js +4 -10
  18. package/dist/policy/core/PolicySource.d.ts +1 -1
  19. package/dist/policy/core/ToolPolicyEngine.d.ts +46 -7
  20. package/dist/policy/core/ToolPolicyEngine.js +73 -16
  21. package/dist/policy/core/compose-decision.d.ts +3 -3
  22. package/dist/policy/core/compose-decision.js +30 -30
  23. package/dist/policy/core/decision-types.d.ts +44 -32
  24. package/dist/policy/core/feature-decision.d.ts +17 -15
  25. package/dist/policy/core/feature-decision.js +11 -13
  26. package/dist/policy/core/pnp-policy-inputs.d.ts +5 -2
  27. package/dist/policy/core/pnp-policy-inputs.js +12 -32
  28. package/dist/policy/core/provenance.d.ts +1 -1
  29. package/dist/policy/core/tool-parameters.d.ts +11 -0
  30. package/dist/policy/core/tool-parameters.js +15 -0
  31. package/dist/policy/engine.d.ts +1 -1
  32. package/dist/policy/sources/PnpPolicySource.d.ts +14 -22
  33. package/dist/policy/sources/PnpPolicySource.js +30 -28
  34. package/dist/runtime/SectionControllerBinding.d.ts +6 -2
  35. package/dist/runtime/SectionControllerBinding.js +21 -15
  36. package/dist/runtime/adapter/subscriber-fanout.d.ts +0 -1
  37. package/dist/runtime/adapter/subscriber-fanout.js +1 -4
  38. package/dist/runtime/composition-emit-scheduler.d.ts +3 -3
  39. package/dist/runtime/composition-emit-scheduler.js +1 -1
  40. package/dist/runtime/content-region.d.ts +0 -4
  41. package/dist/runtime/content-region.js +2 -2
  42. package/dist/runtime/core/SectionEngineCore.d.ts +0 -2
  43. package/dist/runtime/core/SectionEngineCore.js +0 -4
  44. package/dist/runtime/core/cohort.d.ts +0 -5
  45. package/dist/runtime/core/cohort.js +0 -9
  46. package/dist/runtime/core/engine-output.d.ts +3 -2
  47. package/dist/runtime/core/engine-transition.js +3 -2
  48. package/dist/runtime/registration-events.d.ts +11 -14
  49. package/dist/runtime/runtime-id.d.ts +1 -1
  50. package/dist/runtime/runtime-id.js +1 -1
  51. package/dist/runtime/shell-scope.d.ts +4 -4
  52. package/dist/runtime/shell-scope.js +15 -9
  53. package/dist/runtime/tool-host-contract.d.ts +0 -4
  54. package/dist/runtime/tool-host-contract.js +1 -1
  55. package/dist/services/AccessibilityCatalogResolver.d.ts +21 -31
  56. package/dist/services/AccessibilityCatalogResolver.js +29 -42
  57. package/dist/services/ElementToolStateStore.d.ts +32 -61
  58. package/dist/services/ElementToolStateStore.js +37 -67
  59. package/dist/services/HighlightCoordinator.d.ts +9 -21
  60. package/dist/services/HighlightCoordinator.js +52 -80
  61. package/dist/services/RangeSerializer.d.ts +4 -35
  62. package/dist/services/RangeSerializer.js +4 -48
  63. package/dist/services/SSMLExtractor.d.ts +8 -31
  64. package/dist/services/SSMLExtractor.js +18 -40
  65. package/dist/services/TTSService.d.ts +49 -56
  66. package/dist/services/TTSService.js +308 -283
  67. package/dist/services/ToolCoordinator.d.ts +6 -49
  68. package/dist/services/ToolCoordinator.js +25 -61
  69. package/dist/services/ToolRegistry.d.ts +82 -80
  70. package/dist/services/ToolRegistry.js +91 -67
  71. package/dist/services/ToolkitCoordinator.d.ts +83 -81
  72. package/dist/services/ToolkitCoordinator.js +186 -174
  73. package/dist/services/framework-error.d.ts +30 -7
  74. package/dist/services/framework-error.js +10 -13
  75. package/dist/services/interfaces.d.ts +47 -71
  76. package/dist/services/section-controller-types.d.ts +7 -7
  77. package/dist/services/section-session-assignment.js +6 -8
  78. package/dist/services/spoken-audio-cards.d.ts +2 -4
  79. package/dist/services/spoken-audio-cards.js +2 -4
  80. package/dist/services/tool-config-validation.d.ts +5 -7
  81. package/dist/services/tool-config-validation.js +11 -26
  82. package/dist/services/tool-context.d.ts +7 -23
  83. package/dist/services/tool-context.js +99 -53
  84. package/dist/services/tool-failure.d.ts +30 -0
  85. package/dist/services/tool-failure.js +11 -0
  86. package/dist/services/tool-icons.d.ts +1 -2
  87. package/dist/services/tool-icons.js +2 -2
  88. package/dist/services/tool-instance-id.d.ts +8 -6
  89. package/dist/services/tool-instance-id.js +12 -18
  90. package/dist/services/tool-providers/TTSToolProvider.d.ts +6 -43
  91. package/dist/services/tool-providers/TTSToolProvider.js +7 -63
  92. package/dist/services/tool-providers/ToolProviderApi.d.ts +0 -7
  93. package/dist/services/tool-providers/ToolProviderRegistry.d.ts +7 -42
  94. package/dist/services/tool-providers/ToolProviderRegistry.js +21 -63
  95. package/dist/services/tool-request.d.ts +4 -0
  96. package/dist/services/tool-request.js +7 -2
  97. package/dist/services/toolbar-decided-tools.d.ts +1 -0
  98. package/dist/services/toolbar-decided-tools.js +1 -0
  99. package/dist/services/toolbar-items.js +2 -5
  100. package/dist/services/tools-config-normalizer.d.ts +18 -9
  101. package/dist/services/tools-config-normalizer.js +25 -19
  102. package/dist/services/tts/browser-provider.d.ts +2 -5
  103. package/dist/services/tts/browser-provider.js +4 -20
  104. package/dist/services/tts/catalog-span-alignment.js +14 -7
  105. package/dist/services/tts/flat-tree.d.ts +0 -7
  106. package/dist/services/tts/flat-tree.js +2 -2
  107. package/dist/services/tts/generated-speech/dom/to-chunk-inputs.d.ts +2 -2
  108. package/dist/services/tts/generated-speech/index.d.ts +1 -1
  109. package/dist/services/tts/generated-speech/index.js +1 -1
  110. package/dist/services/tts/generated-speech/types.d.ts +1 -1
  111. package/dist/services/tts/generated-speech/types.js +1 -1
  112. package/dist/services/tts/highlight-pipeline/create-highlight-plan.js +10 -12
  113. package/dist/services/tts/highlight-target-resolver.d.ts +12 -0
  114. package/dist/services/tts/math-aware-text-processing.js +10 -29
  115. package/dist/services/tts/math-speech.d.ts +1 -1
  116. package/dist/services/tts/math-speech.js +3 -0
  117. package/dist/services/tts/mathml-sanitization.d.ts +7 -0
  118. package/dist/services/tts/mathml-sanitization.js +9 -1
  119. package/dist/services/tts/provider-options.d.ts +12 -1
  120. package/dist/services/tts/ssml/spoken-text.js +1 -1
  121. package/dist/services/tts/start-failure.d.ts +0 -7
  122. package/dist/services/tts/start-failure.js +1 -1
  123. package/dist/services/tts/text-segmentation.d.ts +5 -0
  124. package/dist/services/tts/text-segmentation.js +13 -10
  125. package/dist/services/tts-runtime-config.d.ts +32 -12
  126. package/dist/services/tts-runtime-config.js +14 -20
  127. package/dist/tools/content-capability-resolution.d.ts +2 -2
  128. package/dist/tools/registration.d.ts +6 -5
  129. package/dist/tools/registration.js +10 -9
  130. package/dist/tools/registrations/toolbar-registration-helpers.d.ts +6 -0
  131. package/dist/tools/registrations/toolbar-registration-helpers.js +6 -0
  132. package/dist/tools/tool-surface-host.js +1 -8
  133. package/package.json +8 -6
  134. package/dist/components/chunks/ItemToolBar-bxwyhr5p.js +0 -2
  135. package/dist/components/chunks/ItemToolBar-rd2bb4p6.js +0 -40
  136. package/dist/components/chunks/sre-engine-jd8cc08x.js +0 -1
  137. package/dist/services/ContextVariableStore.d.ts +0 -113
  138. package/dist/services/ContextVariableStore.js +0 -206
  139. package/dist/services/tts-control-events.d.ts +0 -13
  140. package/dist/services/tts-control-events.js +0 -7
  141. package/dist/utils/logger.d.ts +0 -6
  142. package/dist/utils/logger.js +0 -10
@@ -8,8 +8,6 @@
8
8
  * coordinator's alone: an element bound to a tool (`registerTool` with an
9
9
  * element, or `updateToolElement`) takes a z-index in the tool's layer and comes
10
10
  * to the front of that layer when shown or pressed.
11
- *
12
- * Part of PIE Assessment Toolkit.
13
11
  */
14
12
  import type { ToolCoordinatorApi, ToolState, ToolStateFilter } from "./interfaces.js";
15
13
  /**
@@ -34,70 +32,36 @@ export declare class ToolCoordinator implements ToolCoordinatorApi {
34
32
  /**
35
33
  * Register a tool with the coordinator. Registering a known id keeps its
36
34
  * on/off state and takes the name, the element when one is given, and the
37
- * layer when none was declared before.
38
- *
39
- * @param id Unique tool identifier
40
- * @param name Display name
41
- * @param element DOM element to stack (optional)
42
- * @param layer Z-index layer. Without one the tool stacks on TOOL until a
43
- * registration names one.
35
+ * layer when none was declared before. Without a `layer` the tool stacks on
36
+ * TOOL until a registration names one.
44
37
  */
45
38
  registerTool(id: string, name: string, element?: HTMLElement, layer?: ZIndexLayer): void;
46
39
  /**
47
40
  * Unregister a tool's element binding, keeping its on/off state so a
48
41
  * re-registration of the same id (an item re-render) restores it. Use
49
42
  * {@link releaseTool} on genuine teardown.
50
- *
51
- * @param id Tool identifier
52
43
  */
53
44
  unregisterTool(id: string): void;
54
45
  /**
55
46
  * Fully release a tool: unregister its element binding and discard its
56
47
  * on/off state. Call this on genuine teardown (leaving the item or section
57
48
  * that owns the tool).
58
- *
59
- * @param id Tool identifier
60
49
  */
61
50
  releaseTool(id: string): void;
62
- /**
63
- * Show a tool
64
- *
65
- * @param id Tool identifier
66
- */
67
51
  showTool(id: string): void;
68
- /**
69
- * Hide a tool
70
- *
71
- * @param id Tool identifier
72
- */
73
52
  hideTool(id: string): void;
74
- /**
75
- * Toggle tool visibility
76
- *
77
- * @param id Tool identifier
78
- */
79
53
  toggleTool(id: string): void;
80
- /**
81
- * Check if tool is visible
82
- *
83
- * @param id Tool identifier
84
- */
85
54
  isToolVisible(id: string): boolean;
86
55
  /**
87
56
  * Bring a bound element to the front of its tool's layer. An element no tool
88
57
  * is bound to is left alone.
89
- *
90
- * @param element DOM element to bring forward
91
58
  */
92
59
  bringToFront(element: HTMLElement): void;
93
60
  /**
94
- * Ids of the tools an element registration currently holds.
61
+ * Release every tool, registered or not, and drop the subscribers. The
62
+ * owning toolkit coordinator calls this when it is disposed.
95
63
  */
96
- getRegisteredTools(): string[];
97
- /**
98
- * Get tool element by ID
99
- */
100
- getToolElement(id: string): HTMLElement | null;
64
+ destroy(): void;
101
65
  private setVisible;
102
66
  private detachElement;
103
67
  /**
@@ -112,9 +76,6 @@ export declare class ToolCoordinator implements ToolCoordinatorApi {
112
76
  * The outermost element stacks: binding an element inside the bound one keeps
113
77
  * the binding, so a tool rendered inside a toolbar's floating window stacks
114
78
  * by that window whichever binds first.
115
- *
116
- * @param id Tool identifier
117
- * @param element New DOM element
118
79
  */
119
80
  updateToolElement(id: string, element: HTMLElement): void;
120
81
  /**
@@ -122,11 +83,7 @@ export declare class ToolCoordinator implements ToolCoordinatorApi {
122
83
  * `{ baseId }`, notifying subscribers once.
123
84
  */
124
85
  hideAllTools(filter?: ToolStateFilter): void;
125
- /**
126
- * State of a tool an element registration holds.
127
- *
128
- * @param id Tool identifier
129
- */
86
+ /** State of a tool an element registration holds. */
130
87
  getToolState(id: string): ToolState | undefined;
131
88
  /**
132
89
  * Every visible tool, or every visible instance of one tool with
@@ -8,12 +8,10 @@
8
8
  * coordinator's alone: an element bound to a tool (`registerTool` with an
9
9
  * element, or `updateToolElement`) takes a z-index in the tool's layer and comes
10
10
  * to the front of that layer when shown or pressed.
11
- *
12
- * Part of PIE Assessment Toolkit.
13
11
  */
14
- import { createLogger } from "../utils/logger.js";
12
+ import { createPieLogger, isGlobalDebugEnabled, } from "@pie-players/pie-players-shared/pie";
15
13
  import { parseScopedToolId } from "./tool-instance-id.js";
16
- const log = createLogger("ToolCoordinator");
14
+ const logger = createPieLogger("ToolCoordinator", isGlobalDebugEnabled);
17
15
  /**
18
16
  * Z-index layers for assessment components
19
17
  */
@@ -65,16 +63,16 @@ export class ToolCoordinator {
65
63
  /**
66
64
  * Register a tool with the coordinator. Registering a known id keeps its
67
65
  * on/off state and takes the name, the element when one is given, and the
68
- * layer when none was declared before.
69
- *
70
- * @param id Unique tool identifier
71
- * @param name Display name
72
- * @param element DOM element to stack (optional)
73
- * @param layer Z-index layer. Without one the tool stacks on TOOL until a
74
- * registration names one.
66
+ * layer when none was declared before. Without a `layer` the tool stacks on
67
+ * TOOL until a registration names one.
75
68
  */
76
69
  registerTool(id, name, element, layer) {
77
- log("registerTool called:", { id, name, hasElement: !!element, layer });
70
+ logger.debug("registerTool called:", {
71
+ id,
72
+ name,
73
+ hasElement: !!element,
74
+ layer,
75
+ });
78
76
  let entry = this.tools.get(id);
79
77
  if (entry) {
80
78
  entry.name = name;
@@ -110,8 +108,6 @@ export class ToolCoordinator {
110
108
  * Unregister a tool's element binding, keeping its on/off state so a
111
109
  * re-registration of the same id (an item re-render) restores it. Use
112
110
  * {@link releaseTool} on genuine teardown.
113
- *
114
- * @param id Tool identifier
115
111
  */
116
112
  unregisterTool(id) {
117
113
  const entry = this.tools.get(id);
@@ -124,8 +120,6 @@ export class ToolCoordinator {
124
120
  * Fully release a tool: unregister its element binding and discard its
125
121
  * on/off state. Call this on genuine teardown (leaving the item or section
126
122
  * that owns the tool).
127
- *
128
- * @param id Tool identifier
129
123
  */
130
124
  releaseTool(id) {
131
125
  const entry = this.tools.get(id);
@@ -136,43 +130,28 @@ export class ToolCoordinator {
136
130
  if (entry.isVisible)
137
131
  this.notifyListeners();
138
132
  }
139
- /**
140
- * Show a tool
141
- *
142
- * @param id Tool identifier
143
- */
144
133
  showTool(id) {
145
134
  const entry = this.tools.get(id);
146
135
  if (!entry) {
147
- log(`Tool ${id} not found`);
136
+ logger.debug(`Tool ${id} not found`);
148
137
  return;
149
138
  }
150
139
  if (entry.element)
151
140
  this.bringToFront(entry.element);
152
141
  this.setVisible(entry, true);
153
142
  }
154
- /**
155
- * Hide a tool
156
- *
157
- * @param id Tool identifier
158
- */
159
143
  hideTool(id) {
160
144
  const entry = this.tools.get(id);
161
145
  if (!entry) {
162
- log(`Tool ${id} not found`);
146
+ logger.debug(`Tool ${id} not found`);
163
147
  return;
164
148
  }
165
149
  this.setVisible(entry, false);
166
150
  }
167
- /**
168
- * Toggle tool visibility
169
- *
170
- * @param id Tool identifier
171
- */
172
151
  toggleTool(id) {
173
152
  const entry = this.tools.get(id);
174
153
  if (!entry) {
175
- log(`Tool ${id} not found`);
154
+ logger.debug(`Tool ${id} not found`);
176
155
  return;
177
156
  }
178
157
  if (entry.isVisible) {
@@ -182,19 +161,12 @@ export class ToolCoordinator {
182
161
  this.showTool(id);
183
162
  }
184
163
  }
185
- /**
186
- * Check if tool is visible
187
- *
188
- * @param id Tool identifier
189
- */
190
164
  isToolVisible(id) {
191
165
  return this.tools.get(id)?.isVisible ?? false;
192
166
  }
193
167
  /**
194
168
  * Bring a bound element to the front of its tool's layer. An element no tool
195
169
  * is bound to is left alone.
196
- *
197
- * @param element DOM element to bring forward
198
170
  */
199
171
  bringToFront(element) {
200
172
  const entry = Array.from(this.tools.values()).find((t) => t.element === element);
@@ -203,18 +175,17 @@ export class ToolCoordinator {
203
175
  this.stackOnTop(entry);
204
176
  }
205
177
  /**
206
- * Ids of the tools an element registration currently holds.
178
+ * Release every tool, registered or not, and drop the subscribers. The
179
+ * owning toolkit coordinator calls this when it is disposed.
207
180
  */
208
- getRegisteredTools() {
209
- return Array.from(this.tools.values())
210
- .filter((entry) => entry.registered)
211
- .map((entry) => entry.id);
212
- }
213
- /**
214
- * Get tool element by ID
215
- */
216
- getToolElement(id) {
217
- return this.tools.get(id)?.element ?? null;
181
+ destroy() {
182
+ const anyVisible = Array.from(this.tools.values()).some((entry) => entry.isVisible);
183
+ for (const entry of this.tools.values())
184
+ this.detachElement(entry);
185
+ this.tools.clear();
186
+ if (anyVisible)
187
+ this.notifyListeners();
188
+ this.listeners.clear();
218
189
  }
219
190
  setVisible(entry, visible) {
220
191
  if (entry.isVisible === visible)
@@ -256,14 +227,11 @@ export class ToolCoordinator {
256
227
  * The outermost element stacks: binding an element inside the bound one keeps
257
228
  * the binding, so a tool rendered inside a toolbar's floating window stacks
258
229
  * by that window whichever binds first.
259
- *
260
- * @param id Tool identifier
261
- * @param element New DOM element
262
230
  */
263
231
  updateToolElement(id, element) {
264
232
  const entry = this.tools.get(id);
265
233
  if (!entry?.registered) {
266
- log(`Tool ${id} not found`);
234
+ logger.debug(`Tool ${id} not found`);
267
235
  return;
268
236
  }
269
237
  if (entry.element === element)
@@ -294,11 +262,7 @@ export class ToolCoordinator {
294
262
  if (changed)
295
263
  this.notifyListeners();
296
264
  }
297
- /**
298
- * State of a tool an element registration holds.
299
- *
300
- * @param id Tool identifier
301
- */
265
+ /** State of a tool an element registration holds. */
302
266
  getToolState(id) {
303
267
  const entry = this.tools.get(id);
304
268
  return entry?.registered ? toToolState(entry) : undefined;
@@ -1,18 +1,31 @@
1
1
  /**
2
- * Tool Registry
2
+ * Tool registry: the registration contract every tool declares itself with,
3
+ * the shape validation `register` and `override` run, and the `ToolRegistry`
4
+ * class.
3
5
  *
4
- * Central registry for all assessment tools. Manages tool metadata, visibility logic,
5
- * and button/instance creation. Supports dynamic registration and override by integrators.
6
+ * Layout: the exported contract types come first, ending with
7
+ * `ToolRegistration`, then `assertToolRegistrationShape`, then the class. Its
8
+ * members run from mutation and change observation, through queries and the
9
+ * filters for the second and third passes of tool resolution (relevance in
10
+ * `filterVisibleInContext`, applicability in `filterDecidedToolIds`; the policy
11
+ * engine owns the first), to module loading with its undefined-element
12
+ * warnings and the toolbar and surface render helpers.
6
13
  */
7
14
  import type { I18nProvider } from "@pie-players/pie-players-shared/i18n/types";
15
+ import type { ToolParametersFor } from "@pie-players/pie-players-shared/types";
8
16
  import type { CatalogOwnerSnapshot } from "./AccessibilityCatalogResolver.js";
17
+ import type { ToolPolicyEntry } from "../policy/core/decision-types.js";
9
18
  import type { ToolContext, ToolLevel } from "./tool-context.js";
19
+ import type { ToolScopeLevel } from "./tool-instance-id.js";
10
20
  import { type ToolComponentOverrides } from "../tools/tool-tag-map.js";
11
21
  import type { AccessibilityCatalogResolverApi, ElementToolStateStoreApi, ToolCoordinatorApi, ToolkitCoordinatorApi, TtsServiceApi } from "./interfaces.js";
12
22
  import type { ToolProviderApi } from "./tool-providers/ToolProviderApi.js";
13
- import type { ToolProviderConfig as ToolRuntimeConfig } from "./tools-config-normalizer.js";
23
+ import type { ToolProviderConfig } from "./tools-config-normalizer.js";
14
24
  import type { ToolConfigDiagnostic } from "./tool-config-validation.js";
25
+ import type { ToolFailurePhase } from "./tool-failure.js";
15
26
  export type ToolModuleLoader = () => Promise<unknown>;
27
+ /** Receives a registration callback's throw, from which the registry recovers. */
28
+ export type ToolCallbackFailureHandler = (toolId: string, phase: Extract<ToolFailurePhase, "tool-visibility" | "tool-applicability">, error: unknown) => void;
16
29
  export type ToolRegistryChangeKind = "register" | "override" | "unregister" | "clear" | "component-overrides" | "module-loaders";
17
30
  /** A successful mutation to discoverable or rendering registry state. */
18
31
  export interface ToolRegistryChangeEvent {
@@ -24,18 +37,16 @@ export interface ToolToolbarButtonDefinition {
24
37
  toolId: string;
25
38
  label: string;
26
39
  /**
27
- * Optional to match what the renderer already does: `ItemToolBar.svelte`
28
- * guards on `button.icon`, and `ToolbarItem.icon` is
29
- * already optional, so requiring it here claimed a guarantee nothing relied
30
- * on. A registration that renders a button still has to declare an icon —
40
+ * Optional to match the renderer: `ItemToolBar.svelte` guards on
41
+ * `button.icon`, and `ToolbarItem.icon` is optional too. A registration that
42
+ * renders a button still has to declare an icon —
31
43
  * `assertToolRegistrationShape` enforces that.
32
44
  */
33
45
  icon?: string;
34
46
  /**
35
47
  * FontAwesome icon name, opting this button into `<nds-icon-button>` rendering
36
48
  * where the host enables NDS icons (`ndsIcons`). Absent means the toolbar keeps
37
- * its own button rendering, which is what every capability got before the NDS
38
- * button existed.
49
+ * its own button rendering.
39
50
  *
40
51
  * A declaration rather than a toolId lookup in the toolbar: which capabilities
41
52
  * a deployment renders through the host's design system is a composition-layer
@@ -51,7 +62,7 @@ export interface ToolToolbarButtonDefinition {
51
62
  }
52
63
  export interface ToolbarContext {
53
64
  scope: {
54
- level: ToolLevel;
65
+ level: ToolScopeLevel;
55
66
  scopeId: string;
56
67
  assessmentId?: string;
57
68
  sectionId?: string;
@@ -102,6 +113,12 @@ export interface ToolbarContext {
102
113
  componentOverrides?: ToolComponentOverrides;
103
114
  getResolvedToolContext?: (toolId: string) => ResolvedToolContext | null;
104
115
  getToolRenderParams?: (toolId: string) => Record<string, unknown> | null;
116
+ /**
117
+ * The tool's policy parameters on this toolbar: the item's `toolParameters`
118
+ * entry on an item's own toolbar, else the assessment's `toolParameters` entry.
119
+ * Authored content, so a registration checks what it reads.
120
+ */
121
+ getToolParameters?: <K extends string>(toolId: K) => ToolParametersFor<K> | null;
105
122
  }
106
123
  export interface ToolContextResolverContext {
107
124
  toolId: string;
@@ -222,9 +239,9 @@ export interface HostedToolSize {
222
239
  * renames the registration.
223
240
  */
224
241
  export interface ToolProviderDescriptor {
225
- createProvider: (config: ToolRuntimeConfig | undefined) => ToolProviderApi;
226
- getInitConfig?: (config: ToolRuntimeConfig | undefined) => Record<string, unknown>;
227
- getAuthFetcher?: (config: ToolRuntimeConfig | undefined) => (() => Promise<Record<string, unknown>>) | undefined;
242
+ createProvider: (config: ToolProviderConfig | undefined) => ToolProviderApi;
243
+ getInitConfig?: (config: ToolProviderConfig | undefined) => Record<string, unknown>;
244
+ getAuthFetcher?: (config: ToolProviderConfig | undefined) => (() => Promise<Record<string, unknown>>) | undefined;
228
245
  lazy?: boolean;
229
246
  }
230
247
  export interface ToolToolbarRenderResult {
@@ -293,7 +310,7 @@ export interface ToolSurfaceRenderContext {
293
310
  /** Host slot being filled. */
294
311
  surface: string;
295
312
  /** Feature parameters from the policy decision, if any. */
296
- parameters?: unknown;
313
+ parameters?: Record<string, unknown>;
297
314
  /** Resolved content dependency, when the capability declares one. */
298
315
  content?: unknown;
299
316
  services: ToolSurfaceServices;
@@ -305,7 +322,7 @@ export interface ToolSurfaceRenderContext {
305
322
  */
306
323
  export interface ToolContentDependencyContext {
307
324
  /** Feature parameters from the policy decision, if any. */
308
- parameters?: unknown;
325
+ parameters?: Record<string, unknown>;
309
326
  /**
310
327
  * Owner-scoped catalog cards, or `null` when no resolver is available.
311
328
  *
@@ -333,8 +350,8 @@ export interface ToolContentDependencyContext {
333
350
  * It is intrinsic to the capability, unlike eligibility tier, which is a property
334
351
  * of the program.
335
352
  *
336
- * Two independent things follow from declaring it, and both used to be done by
337
- * naming ids in core:
353
+ * Two independent things follow from declaring it, neither of which needs core
354
+ * to name a capability id:
338
355
  *
339
356
  * 1. **Availability is grant AND content.** The host renders only when policy
340
357
  * granted the feature *and* `resolve` returned something. Neither half
@@ -398,7 +415,8 @@ export interface ToolSurfaceRenderResult {
398
415
  destroy?: () => void;
399
416
  }
400
417
  /**
401
- * Tool registration interface
418
+ * The contract a tool declares itself with; `ToolRegistry.register` validates
419
+ * its shape.
402
420
  */
403
421
  export interface ToolRegistration {
404
422
  /** Unique tool identifier (e.g., 'calculator', 'textToSpeech') */
@@ -489,11 +507,11 @@ export interface ToolRegistration {
489
507
  * validation runs it before {@link ToolRegistration.validateConfig}; a throw is
490
508
  * reported as a diagnostic and the entry passes through unchanged.
491
509
  */
492
- sanitizeConfig?: (config: ToolRuntimeConfig) => ToolRuntimeConfig;
510
+ sanitizeConfig?: (config: ToolProviderConfig) => ToolProviderConfig;
493
511
  /**
494
512
  * Diagnostics for this tool's sanitized `tools.providers.<toolId>` entry.
495
513
  */
496
- validateConfig?: (config: ToolRuntimeConfig) => ToolConfigDiagnostic[];
514
+ validateConfig?: (config: ToolProviderConfig) => ToolConfigDiagnostic[];
497
515
  /**
498
516
  * Optional shell-host lifecycle hooks for hosted (floating) tools.
499
517
  */
@@ -501,17 +519,14 @@ export interface ToolRegistration {
501
519
  onHostedResize?: (size: HostedToolSize, element: HTMLElement, context: HostedToolContext) => void | Promise<void>;
502
520
  onHostedUnmount?: (element: HTMLElement, context: HostedToolContext) => void | Promise<void>;
503
521
  /**
504
- * Pass 2: Tool decides if it's relevant in this context
505
- * Called ONLY if orchestrator has already allowed the tool (Pass 1)
522
+ * Whether the tool is relevant in this context (pass 2). Asked only for a
523
+ * tool policy already allows (pass 1).
506
524
  *
507
525
  * Required for the toolbar activations, and meaningless for `activation:
508
526
  * "region"`: a region capability has no toolbar presence to be relevant to, and
509
527
  * the question it *would* answer — is there anything to show here — is
510
528
  * `requiresAuthoredContent`. A registration that omits this is never returned
511
- * by `getVisibleTools`.
512
- *
513
- * @param context - Rich context about where tool is being evaluated
514
- * @returns true if tool should be visible, false to hide
529
+ * by `filterVisibleInContext`.
515
530
  */
516
531
  isVisibleInContext?(context: ToolContext): boolean;
517
532
  /**
@@ -529,9 +544,6 @@ export interface ToolRegistration {
529
544
  * Declare this only where the tool's own controls provably do nothing:
530
545
  * withdrawing a granted accommodation on a false negative is the more
531
546
  * expensive failure. Omitting it means "applicable".
532
- *
533
- * @param context - The item or element context the tool would act on
534
- * @returns false to withdraw the tool from this context
535
547
  */
536
548
  isApplicableToContent?(context: ToolContext): boolean;
537
549
  /**
@@ -580,56 +592,25 @@ export declare class ToolRegistry {
580
592
  */
581
593
  normalizeToolIds(toolIds: string[]): string[];
582
594
  /**
583
- * Register a tool
584
- *
585
- * @param registration - Tool registration
586
- * @throws Error if toolId is already registered
595
+ * Register a tool. Throws when its `toolId` is already registered.
587
596
  */
588
597
  register(registration: ToolRegistration): void;
589
598
  /**
590
- * Override an existing tool registration
591
- *
592
- * @param registration - New tool registration (must have existing toolId)
599
+ * Replace an existing tool registration. Throws when its `toolId` is not
600
+ * registered.
593
601
  */
594
602
  override(registration: ToolRegistration): void;
595
603
  /**
596
- * Unregister a tool
597
- *
598
- * @param toolId - Tool ID to remove
604
+ * Unregister a tool. An unknown id is a no-op and emits no change.
599
605
  */
600
606
  unregister(toolId: string): void;
601
- /**
602
- * Get a tool registration by ID
603
- *
604
- * @param toolId - Tool ID
605
- * @returns Tool registration or undefined
606
- */
607
607
  get(toolId: string): ToolRegistration | undefined;
608
- /**
609
- * Check if a tool is registered
610
- *
611
- * @param toolId - Tool ID
612
- * @returns true if registered
613
- */
614
608
  has(toolId: string): boolean;
615
- /**
616
- * Get all registered tool IDs
617
- *
618
- * @returns Array of tool IDs
619
- */
609
+ /** Registered tool ids, in registration order. */
620
610
  getAllToolIds(): string[];
621
- /**
622
- * Get all tool registrations
623
- *
624
- * @returns Array of tool registrations
625
- */
611
+ /** Registrations, in registration order. */
626
612
  getAllTools(): ToolRegistration[];
627
- /**
628
- * Get tools that support a specific level
629
- *
630
- * @param level - Tool level (assessment, section, item, passage, element)
631
- * @returns Array of tool registrations that support this level
632
- */
613
+ /** Registrations whose `supportedLevels` include `level`. */
633
614
  getToolsByLevel(level: ToolLevel): ToolRegistration[];
634
615
  /**
635
616
  * Resolve tool activation, defaulting to toolbar-toggle.
@@ -662,16 +643,14 @@ export declare class ToolRegistry {
662
643
  */
663
644
  filterToolIdsByActivation(toolIds: string[], activation: ToolActivation): string[];
664
645
  /**
665
- * Filter tools by visibility in a given context
666
- *
667
- * Pass 2 of the three-pass model: Given a list of allowed tool IDs (from Pass 1),
668
- * ask each tool if it's relevant in this context.
646
+ * Pass 2 of tool resolution: the registrations among `allowedToolIds` (the
647
+ * ids policy allowed in pass 1) that support `context.level` and answer
648
+ * `isVisibleInContext` with `true`.
669
649
  *
670
- * @param allowedToolIds - Tool IDs that passed Pass 1 (orchestrator approval)
671
- * @param context - Context to evaluate
672
- * @returns Array of visible tool registrations
650
+ * @param onFailure - Receives a relevance check's throw; the tool is then not
651
+ * visible. Logs when omitted.
673
652
  */
674
- filterVisibleInContext(allowedToolIds: string[], context: ToolContext): ToolRegistration[];
653
+ filterVisibleInContext(allowedToolIds: string[], context: ToolContext, onFailure?: ToolCallbackFailureHandler): ToolRegistration[];
675
654
  /**
676
655
  * Whether a tool can act on any of the contexts it would be placed against.
677
656
  * Unlike the relevance pass this is a veto: a `false` here removes the tool
@@ -684,13 +663,34 @@ export declare class ToolRegistry {
684
663
  *
685
664
  * @param toolId - Tool to ask
686
665
  * @param contexts - Every context the tool could act on at this placement
666
+ * @param onFailure - Receives the gate's throw; the tool then counts as
667
+ * applicable. Logs when omitted.
687
668
  */
688
- isApplicableToAnyContext(toolId: string, contexts: readonly ToolContext[]): boolean;
669
+ isApplicableToAnyContext(toolId: string, contexts: readonly ToolContext[], onFailure?: ToolCallbackFailureHandler): boolean;
689
670
  /**
690
- * Get tool metadata for building UIs
691
- * Useful for building PNP configuration interfaces
671
+ * Passes 2 and 3 over a policy decision's tools: the ids a surface at `level`
672
+ * shows against `contexts`, in decision order. This is the rule a toolbar
673
+ * applies, for a host that builds its own tool surface.
692
674
  *
693
- * @returns Array of tool metadata (id, name, description, levels, activation)
675
+ * - A tool that does not support `level` is dropped.
676
+ * - Relevance (`isVisibleInContext`) keeps a tool visible in any one context.
677
+ * It does not run for a granted entry (`required` or `alwaysAvailable`),
678
+ * at section level, whose relevance is item-dependent, or when `contexts`
679
+ * is empty, since content that has not resolved cannot rule a tool out.
680
+ * - Applicability (`isApplicableToContent`) then removes a tool that can act
681
+ * on none of `contexts`, granted or not. It does not run at section level.
682
+ *
683
+ * @param entries - The decision's surviving entries (Pass 1), such as
684
+ * `ToolPolicyDecision.visibleTools`
685
+ * @param level - The level of the surface the tools render on
686
+ * @param contexts - Every context the tools could act on at that surface
687
+ * @param onFailure - Receives a relevance or applicability check's throw.
688
+ * Logs when omitted.
689
+ */
690
+ filterDecidedToolIds(entries: readonly Pick<ToolPolicyEntry, "toolId" | "required" | "alwaysAvailable">[], level: ToolLevel, contexts: readonly ToolContext[], onFailure?: ToolCallbackFailureHandler): string[];
691
+ /**
692
+ * Plain metadata for every registration, in registration order, for UIs
693
+ * such as a PNP configuration screen.
694
694
  */
695
695
  getToolMetadata(): Array<{
696
696
  toolId: string;
@@ -765,4 +765,6 @@ export declare class ToolRegistry {
765
765
  * context still win, matching the toolbar path's precedence.
766
766
  */
767
767
  renderForSurface(toolId: string, context: ToolSurfaceRenderContext): ToolSurfaceRenderResult | null;
768
+ /** The registry's component overrides, with the caller's taking precedence. */
769
+ private mergeComponentOverrides;
768
770
  }