@tooluminati/diagnostics 0.1.0 → 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.
@@ -13,7 +13,7 @@ export function createActionAvailabilityTool(provider, name = 'why_is_action_una
13
13
  required: ['actionId'],
14
14
  additionalProperties: false,
15
15
  },
16
- annotations: { readOnlyHint: true },
16
+ annotations: { readOnlyHint: true, debugging: true },
17
17
  validateArgs(args) {
18
18
  if (typeof args !== 'object' ||
19
19
  args === null ||
@@ -38,7 +38,7 @@ export function createListActionsTool(provider, name = 'list_available_actions')
38
38
  properties: {},
39
39
  additionalProperties: false,
40
40
  },
41
- annotations: { readOnlyHint: true },
41
+ annotations: { readOnlyHint: true, debugging: true },
42
42
  execute: () => ({ actions: provider.listActions?.() ?? [] }),
43
43
  };
44
44
  }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=annotations.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"annotations.test.d.ts","sourceRoot":"","sources":["../src/annotations.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,32 @@
1
+ import { expect, it } from 'vitest';
2
+ import { createAppInfoTool, createVisibleToolsTool, createActionAvailabilityTool, createListActionsTool, createFeatureFlagsTool, createHydrationHealthTool, createMountedFormsRegistry, createMountedFormsSummaryTool, createRecentClientErrorsTool, ClientErrorBuffer, createTroubleshootingTimelineTool, TroubleshootingTimelineBuffer, createWorkflowBlockersTool, createWebMcpEnvironmentTool, createWebMcpEnvironmentSummary, } from './index';
3
+ const actions = { getActionAvailability: () => undefined };
4
+ const tools = [
5
+ createAppInfoTool(() => ({ name: 'test' })),
6
+ createVisibleToolsTool(),
7
+ createActionAvailabilityTool(actions),
8
+ createListActionsTool(actions),
9
+ createFeatureFlagsTool(() => []),
10
+ createHydrationHealthTool(() => ({ recoverableErrorCount: 0 })),
11
+ createMountedFormsSummaryTool(createMountedFormsRegistry()),
12
+ createRecentClientErrorsTool(new ClientErrorBuffer()),
13
+ createTroubleshootingTimelineTool(new TroubleshootingTimelineBuffer()),
14
+ createWorkflowBlockersTool({}),
15
+ createWebMcpEnvironmentTool(() => createWebMcpEnvironmentSummary()),
16
+ ];
17
+ it.each(tools.map((tool) => [tool.name, tool]))('%s is annotated as a read-only diagnostic', (_name, tool) => {
18
+ expect(tool.annotations).toMatchObject({
19
+ readOnlyHint: true,
20
+ debugging: true,
21
+ });
22
+ expect(tool.annotations?.consequentialHint).not.toBe(true);
23
+ });
24
+ it.each(tools
25
+ .filter((tool) => [
26
+ 'get_recent_client_errors',
27
+ 'get_troubleshooting_timeline',
28
+ 'get_workflow_blockers',
29
+ ].includes(tool.name))
30
+ .map((tool) => [tool.name, tool]))('%s retains untrusted-content annotation', (_name, tool) => {
31
+ expect(tool.annotations?.untrustedContentHint).toBe(true);
32
+ });
package/dist/app-info.js CHANGED
@@ -7,7 +7,7 @@ export function createAppInfoTool(getInfo, name = 'get_app_info') {
7
7
  properties: {},
8
8
  additionalProperties: false,
9
9
  },
10
- annotations: { readOnlyHint: true },
10
+ annotations: { readOnlyHint: true, debugging: true },
11
11
  execute: () => getInfo(),
12
12
  };
13
13
  }
@@ -20,7 +20,7 @@ export function createVisibleToolsTool(name = 'get_visible_agent_tools') {
20
20
  properties: {},
21
21
  additionalProperties: false,
22
22
  },
23
- annotations: { readOnlyHint: true },
23
+ annotations: { readOnlyHint: true, debugging: true },
24
24
  execute: (_args, context) => ({
25
25
  tools: context.registry.getVisibleToolSummaries(),
26
26
  }),
@@ -0,0 +1,5 @@
1
+ export declare const WEBMCP_DECLARATIVE_FOCUS_STYLES = "\nform:tool-form-active {\n outline: light-dark(#0aadf2, #0aadf2) dashed 1px;\n outline-offset: -1px;\n}\n\n:tool-submit-active {\n outline: light-dark(#fecd10, #fecd10) dashed 1px;\n outline-offset: -1px;\n}\n";
2
+ export declare function isAgentInvokedSubmit(event: Event): boolean;
3
+ export declare function respondWithAgentResult(event: Event, result: unknown): boolean;
4
+ export declare function ensureDeclarativeFocusStyles(): void;
5
+ //# sourceMappingURL=declarative-submit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"declarative-submit.d.ts","sourceRoot":"","sources":["../src/declarative-submit.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,+BAA+B,2NAU3C,CAAC;AAOF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAE1D;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,OAAO,GACd,OAAO,CAST;AAED,wBAAgB,4BAA4B,IAAI,IAAI,CAcnD"}
@@ -0,0 +1,36 @@
1
+ export const WEBMCP_DECLARATIVE_FOCUS_STYLES = `
2
+ form:tool-form-active {
3
+ outline: light-dark(#0aadf2, #0aadf2) dashed 1px;
4
+ outline-offset: -1px;
5
+ }
6
+
7
+ :tool-submit-active {
8
+ outline: light-dark(#fecd10, #fecd10) dashed 1px;
9
+ outline-offset: -1px;
10
+ }
11
+ `;
12
+ export function isAgentInvokedSubmit(event) {
13
+ return Boolean(event.agentInvoked);
14
+ }
15
+ export function respondWithAgentResult(event, result) {
16
+ const submit = event;
17
+ if (!submit.agentInvoked || typeof submit.respondWith !== 'function') {
18
+ return false;
19
+ }
20
+ submit.preventDefault();
21
+ submit.respondWith(Promise.resolve(result));
22
+ return true;
23
+ }
24
+ export function ensureDeclarativeFocusStyles() {
25
+ if (typeof document === 'undefined') {
26
+ return;
27
+ }
28
+ const id = 'tooluminati-webmcp-declarative-focus';
29
+ if (document.getElementById(id)) {
30
+ return;
31
+ }
32
+ const style = document.createElement('style');
33
+ style.id = id;
34
+ style.textContent = WEBMCP_DECLARATIVE_FOCUS_STYLES;
35
+ document.head.appendChild(style);
36
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=declarative-submit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"declarative-submit.test.d.ts","sourceRoot":"","sources":["../src/declarative-submit.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,61 @@
1
+ import { afterEach, describe, expect, it, vi } from 'vitest';
2
+ import { ensureDeclarativeFocusStyles, isAgentInvokedSubmit, respondWithAgentResult, WEBMCP_DECLARATIVE_FOCUS_STYLES, } from './declarative-submit';
3
+ afterEach(() => {
4
+ vi.unstubAllGlobals();
5
+ document.getElementById('tooluminati-webmcp-declarative-focus')?.remove();
6
+ });
7
+ function submit(agentInvoked, respondWith) {
8
+ return Object.assign(new Event('submit', { cancelable: true }), {
9
+ agentInvoked,
10
+ respondWith,
11
+ });
12
+ }
13
+ describe('agent results', () => {
14
+ it.each([false, undefined])('leaves human submits untouched (%s)', (agentInvoked) => {
15
+ const respondWith = vi.fn();
16
+ const event = submit(agentInvoked, respondWith);
17
+ expect(isAgentInvokedSubmit(event)).toBe(false);
18
+ expect(respondWithAgentResult(event, 'done')).toBe(false);
19
+ expect(event.defaultPrevented).toBe(false);
20
+ expect(respondWith).not.toHaveBeenCalled();
21
+ });
22
+ it.each([undefined, true, 'invalid'])('ignores unsupported respondWith %s', (respondWith) => {
23
+ const event = submit(true, respondWith);
24
+ expect(respondWithAgentResult(event, 'done')).toBe(false);
25
+ expect(event.defaultPrevented).toBe(false);
26
+ });
27
+ it('passes a resolved promise synchronously and prevents default submission', async () => {
28
+ const respondWith = vi.fn();
29
+ const event = submit(true, respondWith);
30
+ expect(respondWithAgentResult(event, { saved: true })).toBe(true);
31
+ expect(event.defaultPrevented).toBe(true);
32
+ expect(respondWith).toHaveBeenCalledOnce();
33
+ await expect(respondWith.mock.calls[0][0]).resolves.toEqual({
34
+ saved: true,
35
+ });
36
+ });
37
+ it('preserves rejection for the browser consumer', async () => {
38
+ const error = new Error('save failed');
39
+ const result = Promise.reject(error);
40
+ const respondWith = vi.fn();
41
+ respondWithAgentResult(submit(true, respondWith), result);
42
+ expect(respondWith.mock.calls[0][0]).toBe(result);
43
+ await expect(result).rejects.toBe(error);
44
+ });
45
+ });
46
+ describe('declarative focus styles', () => {
47
+ it('injects one shared style node across repeated calls', () => {
48
+ ensureDeclarativeFocusStyles();
49
+ const style = document.getElementById('tooluminati-webmcp-declarative-focus');
50
+ ensureDeclarativeFocusStyles();
51
+ expect(document.querySelectorAll('#tooluminati-webmcp-declarative-focus')).toHaveLength(1);
52
+ expect(style?.parentElement).toBe(document.head);
53
+ expect(style?.textContent).toBe(WEBMCP_DECLARATIVE_FOCUS_STYLES);
54
+ expect(style?.textContent).toContain('form:tool-form-active');
55
+ expect(style?.textContent).toContain(':tool-submit-active');
56
+ });
57
+ it('does nothing during SSR', () => {
58
+ vi.stubGlobal('document', undefined);
59
+ expect(ensureDeclarativeFocusStyles).not.toThrow();
60
+ });
61
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAE9D,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,kBAAkB,CAAC;IAC3D,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;CACrC;AAQD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4B;IACnD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAoD;IAC5E,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAA2B;gBAEzC,OAAO,GAAE,wBAAwB,GAAG,MAAW;IAgB3D,IAAI,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI;IAkBrC,IAAI,IAAI,kBAAkB,EAAE;IAI5B,KAAK,IAAI,IAAI;CAGd;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,oBAAoB;AACpB,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,qBAAqB,GAC7B,MAAM,IAAI,CAkCZ;AAED,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,iBAAiB,EACzB,IAAI,SAA6B,GAChC,oBAAoB,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE;IAAE,MAAM,EAAE,kBAAkB,EAAE,CAAA;CAAE,CAAC,CAa/E"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAE9D,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,kBAAkB,CAAC;IAC3D,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;CACrC;AAQD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4B;IACnD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAoD;IAC5E,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAA2B;gBAEzC,OAAO,GAAE,wBAAwB,GAAG,MAAW;IAgB3D,IAAI,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI;IAkBrC,IAAI,IAAI,kBAAkB,EAAE;IAI5B,KAAK,IAAI,IAAI;CAGd;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,oBAAoB;AACpB,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,qBAAqB,GAC7B,MAAM,IAAI,CAkCZ;AAED,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,iBAAiB,EACzB,IAAI,SAA6B,GAChC,oBAAoB,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE;IAAE,MAAM,EAAE,kBAAkB,EAAE,CAAA;CAAE,CAAC,CAiB/E"}
package/dist/errors.js CHANGED
@@ -85,7 +85,11 @@ export function createRecentClientErrorsTool(buffer, name = 'get_recent_client_e
85
85
  properties: {},
86
86
  additionalProperties: false,
87
87
  },
88
- annotations: { readOnlyHint: true, untrustedContentHint: true },
88
+ annotations: {
89
+ readOnlyHint: true,
90
+ untrustedContentHint: true,
91
+ debugging: true,
92
+ },
89
93
  execute: () => ({ errors: buffer.list() }),
90
94
  };
91
95
  }
@@ -7,7 +7,7 @@ export function createFeatureFlagsTool(getFlags, name = 'get_feature_flags_summa
7
7
  properties: {},
8
8
  additionalProperties: false,
9
9
  },
10
- annotations: { readOnlyHint: true },
10
+ annotations: { readOnlyHint: true, debugging: true },
11
11
  execute: () => ({ flags: getFlags() }),
12
12
  };
13
13
  }
package/dist/hydration.js CHANGED
@@ -20,7 +20,7 @@ export function createHydrationHealthTool(getHealth, name = 'get_hydration_healt
20
20
  properties: {},
21
21
  additionalProperties: false,
22
22
  },
23
- annotations: { readOnlyHint: true },
23
+ annotations: { readOnlyHint: true, debugging: true },
24
24
  execute: () => getHealth(),
25
25
  };
26
26
  }
package/dist/index.cjs CHANGED
@@ -23,6 +23,7 @@ __export(index_exports, {
23
23
  ClientErrorBuffer: () => ClientErrorBuffer,
24
24
  TROUBLESHOOTING_GUIDANCE: () => TROUBLESHOOTING_GUIDANCE,
25
25
  TroubleshootingTimelineBuffer: () => TroubleshootingTimelineBuffer,
26
+ WEBMCP_DECLARATIVE_FOCUS_STYLES: () => WEBMCP_DECLARATIVE_FOCUS_STYLES,
26
27
  buildTroubleshootingPanelSnapshot: () => buildTroubleshootingPanelSnapshot,
27
28
  computeTroubleshootingPanelState: () => computeTroubleshootingPanelState,
28
29
  createActionAvailabilityTool: () => createActionAvailabilityTool,
@@ -46,13 +47,16 @@ __export(index_exports, {
46
47
  createWebMcpLifecycleCollector: () => createWebMcpLifecycleCollector,
47
48
  createWorkflowBlockersTool: () => createWorkflowBlockersTool,
48
49
  discoverDeclarativeForms: () => discoverDeclarativeForms,
50
+ ensureDeclarativeFocusStyles: () => ensureDeclarativeFocusStyles,
49
51
  filterPanelEvents: () => filterPanelEvents,
50
52
  formSummaryFromMounted: () => formSummaryFromMounted,
51
53
  getGuidanceForClientError: () => getGuidanceForClientError,
52
54
  getGuidanceForEnvironmentCheck: () => getGuidanceForEnvironmentCheck,
53
55
  getGuidanceForTimelineEvent: () => getGuidanceForTimelineEvent,
56
+ isAgentInvokedSubmit: () => isAgentInvokedSubmit,
54
57
  isPanelEnabledByDefault: () => isPanelEnabledByDefault,
55
58
  isPanelUrlOverrideEnabled: () => isPanelUrlOverrideEnabled,
59
+ respondWithAgentResult: () => respondWithAgentResult,
56
60
  serializeTroubleshootingDiagnostics: () => serializeTroubleshootingDiagnostics,
57
61
  timelineEventGroup: () => timelineEventGroup
58
62
  });
@@ -74,7 +78,7 @@ function createActionAvailabilityTool(provider, name = "why_is_action_unavailabl
74
78
  required: ["actionId"],
75
79
  additionalProperties: false
76
80
  },
77
- annotations: { readOnlyHint: true },
81
+ annotations: { readOnlyHint: true, debugging: true },
78
82
  validateArgs(args) {
79
83
  if (typeof args !== "object" || args === null || typeof args.actionId !== "string") {
80
84
  throw new Error("Expected { actionId: string }.");
@@ -97,7 +101,7 @@ function createListActionsTool(provider, name = "list_available_actions") {
97
101
  properties: {},
98
102
  additionalProperties: false
99
103
  },
100
- annotations: { readOnlyHint: true },
104
+ annotations: { readOnlyHint: true, debugging: true },
101
105
  execute: () => ({ actions: provider.listActions?.() ?? [] })
102
106
  };
103
107
  }
@@ -112,7 +116,7 @@ function createAppInfoTool(getInfo, name = "get_app_info") {
112
116
  properties: {},
113
117
  additionalProperties: false
114
118
  },
115
- annotations: { readOnlyHint: true },
119
+ annotations: { readOnlyHint: true, debugging: true },
116
120
  execute: () => getInfo()
117
121
  };
118
122
  }
@@ -125,13 +129,51 @@ function createVisibleToolsTool(name = "get_visible_agent_tools") {
125
129
  properties: {},
126
130
  additionalProperties: false
127
131
  },
128
- annotations: { readOnlyHint: true },
132
+ annotations: { readOnlyHint: true, debugging: true },
129
133
  execute: (_args, context) => ({
130
134
  tools: context.registry.getVisibleToolSummaries()
131
135
  })
132
136
  };
133
137
  }
134
138
 
139
+ // src/declarative-submit.ts
140
+ var WEBMCP_DECLARATIVE_FOCUS_STYLES = `
141
+ form:tool-form-active {
142
+ outline: light-dark(#0aadf2, #0aadf2) dashed 1px;
143
+ outline-offset: -1px;
144
+ }
145
+
146
+ :tool-submit-active {
147
+ outline: light-dark(#fecd10, #fecd10) dashed 1px;
148
+ outline-offset: -1px;
149
+ }
150
+ `;
151
+ function isAgentInvokedSubmit(event) {
152
+ return Boolean(event.agentInvoked);
153
+ }
154
+ function respondWithAgentResult(event, result) {
155
+ const submit = event;
156
+ if (!submit.agentInvoked || typeof submit.respondWith !== "function") {
157
+ return false;
158
+ }
159
+ submit.preventDefault();
160
+ submit.respondWith(Promise.resolve(result));
161
+ return true;
162
+ }
163
+ function ensureDeclarativeFocusStyles() {
164
+ if (typeof document === "undefined") {
165
+ return;
166
+ }
167
+ const id = "tooluminati-webmcp-declarative-focus";
168
+ if (document.getElementById(id)) {
169
+ return;
170
+ }
171
+ const style = document.createElement("style");
172
+ style.id = id;
173
+ style.textContent = WEBMCP_DECLARATIVE_FOCUS_STYLES;
174
+ document.head.appendChild(style);
175
+ }
176
+
135
177
  // src/errors.ts
136
178
  function isDevEnvironment() {
137
179
  return typeof process !== "undefined" && process.env?.NODE_ENV !== "production";
@@ -219,7 +261,11 @@ function createRecentClientErrorsTool(buffer, name = "get_recent_client_errors")
219
261
  properties: {},
220
262
  additionalProperties: false
221
263
  },
222
- annotations: { readOnlyHint: true, untrustedContentHint: true },
264
+ annotations: {
265
+ readOnlyHint: true,
266
+ untrustedContentHint: true,
267
+ debugging: true
268
+ },
223
269
  execute: () => ({ errors: buffer.list() })
224
270
  };
225
271
  }
@@ -234,7 +280,7 @@ function createFeatureFlagsTool(getFlags, name = "get_feature_flags_summary") {
234
280
  properties: {},
235
281
  additionalProperties: false
236
282
  },
237
- annotations: { readOnlyHint: true },
283
+ annotations: { readOnlyHint: true, debugging: true },
238
284
  execute: () => ({ flags: getFlags() })
239
285
  };
240
286
  }
@@ -261,7 +307,7 @@ function createHydrationHealthTool(getHealth, name = "get_hydration_health") {
261
307
  properties: {},
262
308
  additionalProperties: false
263
309
  },
264
- annotations: { readOnlyHint: true },
310
+ annotations: { readOnlyHint: true, debugging: true },
265
311
  execute: () => getHealth()
266
312
  };
267
313
  }
@@ -293,7 +339,7 @@ function createMountedFormsSummaryTool(registry, name = "get_mounted_forms_summa
293
339
  properties: {},
294
340
  additionalProperties: false
295
341
  },
296
- annotations: { readOnlyHint: true },
342
+ annotations: { readOnlyHint: true, debugging: true },
297
343
  execute: () => ({ forms: registry.list() })
298
344
  };
299
345
  }
@@ -562,7 +608,11 @@ function createTroubleshootingTimelineTool(buffer, name = "get_troubleshooting_t
562
608
  },
563
609
  additionalProperties: false
564
610
  },
565
- annotations: { readOnlyHint: true, untrustedContentHint: true },
611
+ annotations: {
612
+ readOnlyHint: true,
613
+ untrustedContentHint: true,
614
+ debugging: true
615
+ },
566
616
  validateArgs(args) {
567
617
  if (typeof args !== "object" || args === null) {
568
618
  return {};
@@ -599,28 +649,44 @@ function createTroubleshootingTimelineTool(buffer, name = "get_troubleshooting_t
599
649
 
600
650
  // src/webmcp-environment.ts
601
651
  var import_core = require("@tooluminati/core");
652
+ var WEBMCP_CONSUMERS = [
653
+ "Chrome DevTools / Model Context Inspector",
654
+ "ChatGPT Site tools (imperative registerTool only)",
655
+ "Safari/Firefox: no native WebMCP"
656
+ ];
602
657
  function createWebMcpEnvironmentSummary(options = {}) {
603
658
  const globalObject = options.globalObject ?? globalThis;
604
659
  let usingNavigatorFallback = false;
605
660
  const documentContext = typeof globalObject.document !== "undefined" ? globalObject.document.modelContext : void 0;
606
- (0, import_core.getModelContext)({
661
+ const modelContext = (0, import_core.getModelContext)({
607
662
  globalObject,
608
663
  onNavigatorFallback: () => {
609
664
  usingNavigatorFallback = true;
610
665
  }
611
666
  });
612
667
  const supported = (0, import_core.isWebMcpSupported)({ globalObject });
668
+ const registerToolAvailable = (0, import_core.isUsableModelContext)(modelContext);
613
669
  const origin = typeof globalObject.location !== "undefined" ? globalObject.location.origin : "unknown";
614
670
  const toolCount = options.registry?.getRegisteredToolNames().length ?? 0;
615
671
  const checks = [];
616
672
  const warnings = [];
673
+ const documentContextStatus = (0, import_core.isUsableModelContext)(documentContext) ? "ok" : supported ? "warn" : "fail";
617
674
  checks.push({
618
675
  id: "document.modelContext",
619
676
  label: "document.modelContext",
620
- value: documentContext ? "available" : "missing",
621
- status: documentContext ? "ok" : "fail",
622
- ...documentContext ? {} : {
623
- hint: "No document.modelContext on this page. Enable WebMCP in Chrome or attach the Model Context Inspector Extension."
677
+ value: (0, import_core.isUsableModelContext)(documentContext) ? "available" : supported ? "missing; using fallback" : "missing",
678
+ status: documentContextStatus,
679
+ ...documentContextStatus === "ok" ? {} : {
680
+ hint: supported ? "No document.modelContext.registerTool on this page, but WebMCP is available through navigator.modelContext in this Chrome build." : "No document.modelContext.registerTool on this page. Enable WebMCP in Chrome or attach the Model Context Inspector Extension."
681
+ }
682
+ });
683
+ checks.push({
684
+ id: "registerTool",
685
+ label: "registerTool",
686
+ value: registerToolAvailable ? "available" : "missing",
687
+ status: registerToolAvailable ? "ok" : "fail",
688
+ ...registerToolAvailable ? {} : {
689
+ hint: 'Feature-detect typeof modelContext.registerTool === "function" before registering tools.'
624
690
  }
625
691
  });
626
692
  checks.push({
@@ -632,6 +698,13 @@ function createWebMcpEnvironmentSummary(options = {}) {
632
698
  hint: "Deprecated navigator.modelContext path detected. Migrate to document.modelContext."
633
699
  } : {}
634
700
  });
701
+ checks.push({
702
+ id: "origin-trial",
703
+ label: "Origin trial / flag",
704
+ value: "required until the API ships",
705
+ status: "muted",
706
+ hint: "Chrome 149\u2013156 need #enable-webmcp-testing or an Origin-Trial token. Chrome 157 is a target, not a ship contract."
707
+ });
635
708
  const originIsolation = detectOriginIsolationIssue(globalObject);
636
709
  checks.push({
637
710
  id: "origin-isolation",
@@ -654,6 +727,13 @@ function createWebMcpEnvironmentSummary(options = {}) {
654
727
  if (permissionsPolicy.warning) {
655
728
  warnings.push(permissionsPolicy.warning);
656
729
  }
730
+ checks.push({
731
+ id: "consumers",
732
+ label: "Known agent consumers",
733
+ value: WEBMCP_CONSUMERS.join("; "),
734
+ status: "muted",
735
+ hint: "Treat tools as progressive enhancement. Declarative forms are Chrome-only today; ChatGPT Site tools see registerTool only."
736
+ });
657
737
  if (toolCount === 0 && supported) {
658
738
  warnings.push("No tools registered yet.");
659
739
  checks.push({
@@ -672,6 +752,8 @@ function createWebMcpEnvironmentSummary(options = {}) {
672
752
  toolCount,
673
753
  origin,
674
754
  usingNavigatorFallback,
755
+ registerToolAvailable,
756
+ consumers: WEBMCP_CONSUMERS,
675
757
  checks,
676
758
  warnings
677
759
  };
@@ -733,7 +815,7 @@ function createWebMcpEnvironmentTool(getSummary, name = "get_webmcp_environment"
733
815
  properties: {},
734
816
  additionalProperties: false
735
817
  },
736
- annotations: { readOnlyHint: true },
818
+ annotations: { readOnlyHint: true, debugging: true },
737
819
  execute: () => getSummary()
738
820
  };
739
821
  }
@@ -748,7 +830,11 @@ function createWorkflowBlockersTool(sources, name = "get_workflow_blockers") {
748
830
  properties: {},
749
831
  additionalProperties: false
750
832
  },
751
- annotations: { readOnlyHint: true, untrustedContentHint: true },
833
+ annotations: {
834
+ readOnlyHint: true,
835
+ untrustedContentHint: true,
836
+ debugging: true
837
+ },
752
838
  execute: () => {
753
839
  const actions = sources.actionProvider?.listActions?.().map((action) => ({
754
840
  actionId: action.actionId,
@@ -1164,6 +1250,7 @@ function filterPanelEvents(events, filter) {
1164
1250
  ClientErrorBuffer,
1165
1251
  TROUBLESHOOTING_GUIDANCE,
1166
1252
  TroubleshootingTimelineBuffer,
1253
+ WEBMCP_DECLARATIVE_FOCUS_STYLES,
1167
1254
  buildTroubleshootingPanelSnapshot,
1168
1255
  computeTroubleshootingPanelState,
1169
1256
  createActionAvailabilityTool,
@@ -1187,13 +1274,16 @@ function filterPanelEvents(events, filter) {
1187
1274
  createWebMcpLifecycleCollector,
1188
1275
  createWorkflowBlockersTool,
1189
1276
  discoverDeclarativeForms,
1277
+ ensureDeclarativeFocusStyles,
1190
1278
  filterPanelEvents,
1191
1279
  formSummaryFromMounted,
1192
1280
  getGuidanceForClientError,
1193
1281
  getGuidanceForEnvironmentCheck,
1194
1282
  getGuidanceForTimelineEvent,
1283
+ isAgentInvokedSubmit,
1195
1284
  isPanelEnabledByDefault,
1196
1285
  isPanelUrlOverrideEnabled,
1286
+ respondWithAgentResult,
1197
1287
  serializeTroubleshootingDiagnostics,
1198
1288
  timelineEventGroup
1199
1289
  });
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@
3
3
  */
4
4
  export * from './action-availability';
5
5
  export * from './app-info';
6
+ export * from './declarative-submit';
6
7
  export * from './errors';
7
8
  export * from './feature-flags';
8
9
  export * from './hydration';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,uBAAuB,CAAC;AACtC,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,uBAAuB,CAAC;AACtC,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yBAAyB,CAAC"}
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ function createActionAvailabilityTool(provider, name = "why_is_action_unavailabl
14
14
  required: ["actionId"],
15
15
  additionalProperties: false
16
16
  },
17
- annotations: { readOnlyHint: true },
17
+ annotations: { readOnlyHint: true, debugging: true },
18
18
  validateArgs(args) {
19
19
  if (typeof args !== "object" || args === null || typeof args.actionId !== "string") {
20
20
  throw new Error("Expected { actionId: string }.");
@@ -37,7 +37,7 @@ function createListActionsTool(provider, name = "list_available_actions") {
37
37
  properties: {},
38
38
  additionalProperties: false
39
39
  },
40
- annotations: { readOnlyHint: true },
40
+ annotations: { readOnlyHint: true, debugging: true },
41
41
  execute: () => ({ actions: provider.listActions?.() ?? [] })
42
42
  };
43
43
  }
@@ -52,7 +52,7 @@ function createAppInfoTool(getInfo, name = "get_app_info") {
52
52
  properties: {},
53
53
  additionalProperties: false
54
54
  },
55
- annotations: { readOnlyHint: true },
55
+ annotations: { readOnlyHint: true, debugging: true },
56
56
  execute: () => getInfo()
57
57
  };
58
58
  }
@@ -65,13 +65,51 @@ function createVisibleToolsTool(name = "get_visible_agent_tools") {
65
65
  properties: {},
66
66
  additionalProperties: false
67
67
  },
68
- annotations: { readOnlyHint: true },
68
+ annotations: { readOnlyHint: true, debugging: true },
69
69
  execute: (_args, context) => ({
70
70
  tools: context.registry.getVisibleToolSummaries()
71
71
  })
72
72
  };
73
73
  }
74
74
 
75
+ // src/declarative-submit.ts
76
+ var WEBMCP_DECLARATIVE_FOCUS_STYLES = `
77
+ form:tool-form-active {
78
+ outline: light-dark(#0aadf2, #0aadf2) dashed 1px;
79
+ outline-offset: -1px;
80
+ }
81
+
82
+ :tool-submit-active {
83
+ outline: light-dark(#fecd10, #fecd10) dashed 1px;
84
+ outline-offset: -1px;
85
+ }
86
+ `;
87
+ function isAgentInvokedSubmit(event) {
88
+ return Boolean(event.agentInvoked);
89
+ }
90
+ function respondWithAgentResult(event, result) {
91
+ const submit = event;
92
+ if (!submit.agentInvoked || typeof submit.respondWith !== "function") {
93
+ return false;
94
+ }
95
+ submit.preventDefault();
96
+ submit.respondWith(Promise.resolve(result));
97
+ return true;
98
+ }
99
+ function ensureDeclarativeFocusStyles() {
100
+ if (typeof document === "undefined") {
101
+ return;
102
+ }
103
+ const id = "tooluminati-webmcp-declarative-focus";
104
+ if (document.getElementById(id)) {
105
+ return;
106
+ }
107
+ const style = document.createElement("style");
108
+ style.id = id;
109
+ style.textContent = WEBMCP_DECLARATIVE_FOCUS_STYLES;
110
+ document.head.appendChild(style);
111
+ }
112
+
75
113
  // src/errors.ts
76
114
  function isDevEnvironment() {
77
115
  return typeof process !== "undefined" && process.env?.NODE_ENV !== "production";
@@ -159,7 +197,11 @@ function createRecentClientErrorsTool(buffer, name = "get_recent_client_errors")
159
197
  properties: {},
160
198
  additionalProperties: false
161
199
  },
162
- annotations: { readOnlyHint: true, untrustedContentHint: true },
200
+ annotations: {
201
+ readOnlyHint: true,
202
+ untrustedContentHint: true,
203
+ debugging: true
204
+ },
163
205
  execute: () => ({ errors: buffer.list() })
164
206
  };
165
207
  }
@@ -174,7 +216,7 @@ function createFeatureFlagsTool(getFlags, name = "get_feature_flags_summary") {
174
216
  properties: {},
175
217
  additionalProperties: false
176
218
  },
177
- annotations: { readOnlyHint: true },
219
+ annotations: { readOnlyHint: true, debugging: true },
178
220
  execute: () => ({ flags: getFlags() })
179
221
  };
180
222
  }
@@ -201,7 +243,7 @@ function createHydrationHealthTool(getHealth, name = "get_hydration_health") {
201
243
  properties: {},
202
244
  additionalProperties: false
203
245
  },
204
- annotations: { readOnlyHint: true },
246
+ annotations: { readOnlyHint: true, debugging: true },
205
247
  execute: () => getHealth()
206
248
  };
207
249
  }
@@ -233,7 +275,7 @@ function createMountedFormsSummaryTool(registry, name = "get_mounted_forms_summa
233
275
  properties: {},
234
276
  additionalProperties: false
235
277
  },
236
- annotations: { readOnlyHint: true },
278
+ annotations: { readOnlyHint: true, debugging: true },
237
279
  execute: () => ({ forms: registry.list() })
238
280
  };
239
281
  }
@@ -502,7 +544,11 @@ function createTroubleshootingTimelineTool(buffer, name = "get_troubleshooting_t
502
544
  },
503
545
  additionalProperties: false
504
546
  },
505
- annotations: { readOnlyHint: true, untrustedContentHint: true },
547
+ annotations: {
548
+ readOnlyHint: true,
549
+ untrustedContentHint: true,
550
+ debugging: true
551
+ },
506
552
  validateArgs(args) {
507
553
  if (typeof args !== "object" || args === null) {
508
554
  return {};
@@ -540,30 +586,47 @@ function createTroubleshootingTimelineTool(buffer, name = "get_troubleshooting_t
540
586
  // src/webmcp-environment.ts
541
587
  import {
542
588
  getModelContext,
589
+ isUsableModelContext,
543
590
  isWebMcpSupported
544
591
  } from "@tooluminati/core";
592
+ var WEBMCP_CONSUMERS = [
593
+ "Chrome DevTools / Model Context Inspector",
594
+ "ChatGPT Site tools (imperative registerTool only)",
595
+ "Safari/Firefox: no native WebMCP"
596
+ ];
545
597
  function createWebMcpEnvironmentSummary(options = {}) {
546
598
  const globalObject = options.globalObject ?? globalThis;
547
599
  let usingNavigatorFallback = false;
548
600
  const documentContext = typeof globalObject.document !== "undefined" ? globalObject.document.modelContext : void 0;
549
- getModelContext({
601
+ const modelContext = getModelContext({
550
602
  globalObject,
551
603
  onNavigatorFallback: () => {
552
604
  usingNavigatorFallback = true;
553
605
  }
554
606
  });
555
607
  const supported = isWebMcpSupported({ globalObject });
608
+ const registerToolAvailable = isUsableModelContext(modelContext);
556
609
  const origin = typeof globalObject.location !== "undefined" ? globalObject.location.origin : "unknown";
557
610
  const toolCount = options.registry?.getRegisteredToolNames().length ?? 0;
558
611
  const checks = [];
559
612
  const warnings = [];
613
+ const documentContextStatus = isUsableModelContext(documentContext) ? "ok" : supported ? "warn" : "fail";
560
614
  checks.push({
561
615
  id: "document.modelContext",
562
616
  label: "document.modelContext",
563
- value: documentContext ? "available" : "missing",
564
- status: documentContext ? "ok" : "fail",
565
- ...documentContext ? {} : {
566
- hint: "No document.modelContext on this page. Enable WebMCP in Chrome or attach the Model Context Inspector Extension."
617
+ value: isUsableModelContext(documentContext) ? "available" : supported ? "missing; using fallback" : "missing",
618
+ status: documentContextStatus,
619
+ ...documentContextStatus === "ok" ? {} : {
620
+ hint: supported ? "No document.modelContext.registerTool on this page, but WebMCP is available through navigator.modelContext in this Chrome build." : "No document.modelContext.registerTool on this page. Enable WebMCP in Chrome or attach the Model Context Inspector Extension."
621
+ }
622
+ });
623
+ checks.push({
624
+ id: "registerTool",
625
+ label: "registerTool",
626
+ value: registerToolAvailable ? "available" : "missing",
627
+ status: registerToolAvailable ? "ok" : "fail",
628
+ ...registerToolAvailable ? {} : {
629
+ hint: 'Feature-detect typeof modelContext.registerTool === "function" before registering tools.'
567
630
  }
568
631
  });
569
632
  checks.push({
@@ -575,6 +638,13 @@ function createWebMcpEnvironmentSummary(options = {}) {
575
638
  hint: "Deprecated navigator.modelContext path detected. Migrate to document.modelContext."
576
639
  } : {}
577
640
  });
641
+ checks.push({
642
+ id: "origin-trial",
643
+ label: "Origin trial / flag",
644
+ value: "required until the API ships",
645
+ status: "muted",
646
+ hint: "Chrome 149\u2013156 need #enable-webmcp-testing or an Origin-Trial token. Chrome 157 is a target, not a ship contract."
647
+ });
578
648
  const originIsolation = detectOriginIsolationIssue(globalObject);
579
649
  checks.push({
580
650
  id: "origin-isolation",
@@ -597,6 +667,13 @@ function createWebMcpEnvironmentSummary(options = {}) {
597
667
  if (permissionsPolicy.warning) {
598
668
  warnings.push(permissionsPolicy.warning);
599
669
  }
670
+ checks.push({
671
+ id: "consumers",
672
+ label: "Known agent consumers",
673
+ value: WEBMCP_CONSUMERS.join("; "),
674
+ status: "muted",
675
+ hint: "Treat tools as progressive enhancement. Declarative forms are Chrome-only today; ChatGPT Site tools see registerTool only."
676
+ });
600
677
  if (toolCount === 0 && supported) {
601
678
  warnings.push("No tools registered yet.");
602
679
  checks.push({
@@ -615,6 +692,8 @@ function createWebMcpEnvironmentSummary(options = {}) {
615
692
  toolCount,
616
693
  origin,
617
694
  usingNavigatorFallback,
695
+ registerToolAvailable,
696
+ consumers: WEBMCP_CONSUMERS,
618
697
  checks,
619
698
  warnings
620
699
  };
@@ -676,7 +755,7 @@ function createWebMcpEnvironmentTool(getSummary, name = "get_webmcp_environment"
676
755
  properties: {},
677
756
  additionalProperties: false
678
757
  },
679
- annotations: { readOnlyHint: true },
758
+ annotations: { readOnlyHint: true, debugging: true },
680
759
  execute: () => getSummary()
681
760
  };
682
761
  }
@@ -691,7 +770,11 @@ function createWorkflowBlockersTool(sources, name = "get_workflow_blockers") {
691
770
  properties: {},
692
771
  additionalProperties: false
693
772
  },
694
- annotations: { readOnlyHint: true, untrustedContentHint: true },
773
+ annotations: {
774
+ readOnlyHint: true,
775
+ untrustedContentHint: true,
776
+ debugging: true
777
+ },
695
778
  execute: () => {
696
779
  const actions = sources.actionProvider?.listActions?.().map((action) => ({
697
780
  actionId: action.actionId,
@@ -1106,6 +1189,7 @@ export {
1106
1189
  ClientErrorBuffer,
1107
1190
  TROUBLESHOOTING_GUIDANCE,
1108
1191
  TroubleshootingTimelineBuffer,
1192
+ WEBMCP_DECLARATIVE_FOCUS_STYLES,
1109
1193
  buildTroubleshootingPanelSnapshot,
1110
1194
  computeTroubleshootingPanelState,
1111
1195
  createActionAvailabilityTool,
@@ -1129,13 +1213,16 @@ export {
1129
1213
  createWebMcpLifecycleCollector,
1130
1214
  createWorkflowBlockersTool,
1131
1215
  discoverDeclarativeForms,
1216
+ ensureDeclarativeFocusStyles,
1132
1217
  filterPanelEvents,
1133
1218
  formSummaryFromMounted,
1134
1219
  getGuidanceForClientError,
1135
1220
  getGuidanceForEnvironmentCheck,
1136
1221
  getGuidanceForTimelineEvent,
1222
+ isAgentInvokedSubmit,
1137
1223
  isPanelEnabledByDefault,
1138
1224
  isPanelUrlOverrideEnabled,
1225
+ respondWithAgentResult,
1139
1226
  serializeTroubleshootingDiagnostics,
1140
1227
  timelineEventGroup
1141
1228
  };
@@ -26,7 +26,7 @@ export function createMountedFormsSummaryTool(registry, name = 'get_mounted_form
26
26
  properties: {},
27
27
  additionalProperties: false,
28
28
  },
29
- annotations: { readOnlyHint: true },
29
+ annotations: { readOnlyHint: true, debugging: true },
30
30
  execute: () => ({ forms: registry.list() }),
31
31
  };
32
32
  }
@@ -1 +1 @@
1
- {"version":3,"file":"timeline.d.ts","sourceRoot":"","sources":["../src/timeline.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"timeline.d.ts","sourceRoot":"","sources":["../src/timeline.ts"],"names":[],"mappings":"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"}
package/dist/timeline.js CHANGED
@@ -266,7 +266,11 @@ export function createTroubleshootingTimelineTool(buffer, name = 'get_troublesho
266
266
  },
267
267
  additionalProperties: false,
268
268
  },
269
- annotations: { readOnlyHint: true, untrustedContentHint: true },
269
+ annotations: {
270
+ readOnlyHint: true,
271
+ untrustedContentHint: true,
272
+ debugging: true,
273
+ },
270
274
  validateArgs(args) {
271
275
  if (typeof args !== 'object' || args === null) {
272
276
  return {};
@@ -5,7 +5,7 @@ import { TroubleshootingTimelineBuffer } from './timeline';
5
5
  import { createWebMcpEnvironmentSummary } from './webmcp-environment';
6
6
  const globalObject = {
7
7
  window: {},
8
- document: { modelContext: {} },
8
+ document: { modelContext: { registerTool: () => undefined } },
9
9
  location: { origin: 'https://app.test' },
10
10
  };
11
11
  describe('troubleshooting panel snapshot', () => {
@@ -23,7 +23,10 @@ describe('troubleshooting panel snapshot', () => {
23
23
  environment: () => createWebMcpEnvironmentSummary({
24
24
  globalObject: {
25
25
  window: {},
26
- document: { modelContext: {}, domain: 'x.com' },
26
+ document: {
27
+ modelContext: { registerTool: () => undefined },
28
+ domain: 'x.com',
29
+ },
27
30
  location: { origin: 'https://app.test' },
28
31
  },
29
32
  }),
@@ -11,6 +11,8 @@ export interface WebMcpEnvironmentSummary {
11
11
  toolCount: number;
12
12
  origin: string;
13
13
  usingNavigatorFallback: boolean;
14
+ registerToolAvailable: boolean;
15
+ consumers: string[];
14
16
  checks: WebMcpEnvironmentCheck[];
15
17
  warnings: string[];
16
18
  }
@@ -1 +1 @@
1
- {"version":3,"file":"webmcp-environment.d.ts","sourceRoot":"","sources":["../src/webmcp-environment.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,oBAAoB,EAC1B,MAAM,mBAAmB,CAAC;AAE3B,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IACzC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,sBAAsB,EAAE,OAAO,CAAC;IAChC,MAAM,EAAE,sBAAsB,EAAE,CAAC;IACjC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IACtC,YAAY,CAAC,EAAE,OAAO,UAAU,CAAC;CAClC;AAED,wBAAgB,8BAA8B,CAC5C,OAAO,GAAE,+BAAoC,GAC5C,wBAAwB,CAoG1B;AA8ED,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,MAAM,wBAAwB,EAC1C,IAAI,SAA2B,GAC9B,oBAAoB,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,wBAAwB,CAAC,CAavE"}
1
+ {"version":3,"file":"webmcp-environment.d.ts","sourceRoot":"","sources":["../src/webmcp-environment.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,cAAc,EACnB,KAAK,oBAAoB,EAC1B,MAAM,mBAAmB,CAAC;AAE3B,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IACzC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,sBAAsB,EAAE,OAAO,CAAC;IAChC,qBAAqB,EAAE,OAAO,CAAC;IAC/B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,sBAAsB,EAAE,CAAC;IACjC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IACtC,YAAY,CAAC,EAAE,OAAO,UAAU,CAAC;CAClC;AAQD,wBAAgB,8BAA8B,CAC5C,OAAO,GAAE,+BAAoC,GAC5C,wBAAwB,CAsJ1B;AA8ED,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,MAAM,wBAAwB,EAC1C,IAAI,SAA2B,GAC9B,oBAAoB,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,wBAAwB,CAAC,CAavE"}
@@ -1,4 +1,9 @@
1
- import { getModelContext, isWebMcpSupported, } from '@tooluminati/core';
1
+ import { getModelContext, isUsableModelContext, isWebMcpSupported, } from '@tooluminati/core';
2
+ const WEBMCP_CONSUMERS = [
3
+ 'Chrome DevTools / Model Context Inspector',
4
+ 'ChatGPT Site tools (imperative registerTool only)',
5
+ 'Safari/Firefox: no native WebMCP',
6
+ ];
2
7
  export function createWebMcpEnvironmentSummary(options = {}) {
3
8
  const globalObject = options.globalObject ?? globalThis;
4
9
  let usingNavigatorFallback = false;
@@ -6,29 +11,56 @@ export function createWebMcpEnvironmentSummary(options = {}) {
6
11
  ? globalObject.document
7
12
  .modelContext
8
13
  : undefined;
9
- getModelContext({
14
+ const modelContext = getModelContext({
10
15
  globalObject,
11
16
  onNavigatorFallback: () => {
12
17
  usingNavigatorFallback = true;
13
18
  },
14
19
  });
15
20
  const supported = isWebMcpSupported({ globalObject });
21
+ const registerToolAvailable = isUsableModelContext(modelContext);
16
22
  const origin = typeof globalObject.location !== 'undefined'
17
23
  ? globalObject.location.origin
18
24
  : 'unknown';
19
25
  const toolCount = options.registry?.getRegisteredToolNames().length ?? 0;
20
26
  const checks = [];
21
27
  const warnings = [];
28
+ const documentContextStatus = isUsableModelContext(documentContext)
29
+ ? 'ok'
30
+ : supported
31
+ ? 'warn'
32
+ : 'fail';
22
33
  checks.push({
23
34
  id: 'document.modelContext',
24
35
  label: 'document.modelContext',
25
- value: documentContext ? 'available' : 'missing',
26
- status: documentContext ? 'ok' : 'fail',
27
- ...(documentContext
36
+ value: isUsableModelContext(documentContext)
37
+ ? 'available'
38
+ : supported
39
+ ? 'missing; using fallback'
40
+ : 'missing',
41
+ status: documentContextStatus,
42
+ ...(documentContextStatus === 'ok'
28
43
  ? {}
29
44
  : {
30
- hint: 'No document.modelContext on this page. Enable WebMCP in Chrome ' +
31
- 'or attach the Model Context Inspector Extension.',
45
+ hint: supported
46
+ ? 'No document.modelContext.registerTool on this page, ' +
47
+ 'but WebMCP is available through navigator.modelContext ' +
48
+ 'in this Chrome build.'
49
+ : 'No document.modelContext.registerTool on this page. ' +
50
+ 'Enable WebMCP in Chrome or attach the Model Context ' +
51
+ 'Inspector Extension.',
52
+ }),
53
+ });
54
+ checks.push({
55
+ id: 'registerTool',
56
+ label: 'registerTool',
57
+ value: registerToolAvailable ? 'available' : 'missing',
58
+ status: registerToolAvailable ? 'ok' : 'fail',
59
+ ...(registerToolAvailable
60
+ ? {}
61
+ : {
62
+ hint: 'Feature-detect typeof modelContext.registerTool === ' +
63
+ '"function" before registering tools.',
32
64
  }),
33
65
  });
34
66
  checks.push({
@@ -38,11 +70,19 @@ export function createWebMcpEnvironmentSummary(options = {}) {
38
70
  status: usingNavigatorFallback ? 'warn' : 'ok',
39
71
  ...(usingNavigatorFallback
40
72
  ? {
41
- hint: 'Deprecated navigator.modelContext path detected. Migrate to ' +
42
- 'document.modelContext.',
73
+ hint: 'Deprecated navigator.modelContext path detected. Migrate ' +
74
+ 'to document.modelContext.',
43
75
  }
44
76
  : {}),
45
77
  });
78
+ checks.push({
79
+ id: 'origin-trial',
80
+ label: 'Origin trial / flag',
81
+ value: 'required until the API ships',
82
+ status: 'muted',
83
+ hint: 'Chrome 149–156 need #enable-webmcp-testing or an Origin-Trial ' +
84
+ 'token. Chrome 157 is a target, not a ship contract.',
85
+ });
46
86
  const originIsolation = detectOriginIsolationIssue(globalObject);
47
87
  checks.push({
48
88
  id: 'origin-isolation',
@@ -65,6 +105,14 @@ export function createWebMcpEnvironmentSummary(options = {}) {
65
105
  if (permissionsPolicy.warning) {
66
106
  warnings.push(permissionsPolicy.warning);
67
107
  }
108
+ checks.push({
109
+ id: 'consumers',
110
+ label: 'Known agent consumers',
111
+ value: WEBMCP_CONSUMERS.join('; '),
112
+ status: 'muted',
113
+ hint: 'Treat tools as progressive enhancement. Declarative forms are ' +
114
+ 'Chrome-only today; ChatGPT Site tools see registerTool only.',
115
+ });
68
116
  if (toolCount === 0 && supported) {
69
117
  warnings.push('No tools registered yet.');
70
118
  checks.push({
@@ -84,6 +132,8 @@ export function createWebMcpEnvironmentSummary(options = {}) {
84
132
  toolCount,
85
133
  origin,
86
134
  usingNavigatorFallback,
135
+ registerToolAvailable,
136
+ consumers: WEBMCP_CONSUMERS,
87
137
  checks,
88
138
  warnings,
89
139
  };
@@ -150,7 +200,7 @@ export function createWebMcpEnvironmentTool(getSummary, name = 'get_webmcp_envir
150
200
  properties: {},
151
201
  additionalProperties: false,
152
202
  },
153
- annotations: { readOnlyHint: true },
203
+ annotations: { readOnlyHint: true, debugging: true },
154
204
  execute: () => getSummary(),
155
205
  };
156
206
  }
@@ -21,12 +21,32 @@ describe('createWebMcpEnvironmentSummary', () => {
21
21
  registry,
22
22
  globalObject: {
23
23
  window: {},
24
- document: { modelContext: {} },
24
+ document: { modelContext: { registerTool: () => undefined } },
25
25
  location: { origin: 'https://app.test' },
26
26
  },
27
27
  });
28
28
  expect(summary.toolCount).toBe(1);
29
29
  expect(summary.supported).toBe(true);
30
+ expect(summary.registerToolAvailable).toBe(true);
31
+ expect(summary.consumers.length).toBeGreaterThan(0);
32
+ expect(summary.checks.some((check) => check.id === 'origin-trial')).toBe(true);
33
+ });
34
+ it('supports Chrome 149 navigator.modelContext fallback', () => {
35
+ const summary = createWebMcpEnvironmentSummary({
36
+ globalObject: {
37
+ window: {},
38
+ document: {},
39
+ navigator: { modelContext: { registerTool: () => undefined } },
40
+ location: { origin: 'https://app.test' },
41
+ },
42
+ });
43
+ const documentCheck = summary.checks.find((check) => check.id === 'document.modelContext');
44
+ const navigatorCheck = summary.checks.find((check) => check.id === 'navigator.modelContext');
45
+ expect(summary.supported).toBe(true);
46
+ expect(summary.usingNavigatorFallback).toBe(true);
47
+ expect(documentCheck?.status).toBe('warn');
48
+ expect(documentCheck?.value).toBe('missing; using fallback');
49
+ expect(navigatorCheck?.status).toBe('warn');
30
50
  });
31
51
  it('warns when document.domain is set', () => {
32
52
  const summary = createWebMcpEnvironmentSummary({
@@ -47,3 +67,23 @@ describe('createWebMcpEnvironmentTool', () => {
47
67
  expect(result).toHaveProperty('checks');
48
68
  });
49
69
  });
70
+ it.each([undefined, {}, { registerTool: true }])('reports unsupported malformed context %s', (modelContext) => {
71
+ const summary = createWebMcpEnvironmentSummary({
72
+ globalObject: {
73
+ window: {},
74
+ document: { modelContext },
75
+ },
76
+ });
77
+ expect(summary.supported).toBe(false);
78
+ expect(summary.registerToolAvailable).toBe(false);
79
+ expect(summary.usingNavigatorFallback).toBe(false);
80
+ expect(summary.checks).toContainEqual(expect.objectContaining({ id: 'registerTool', status: 'fail' }));
81
+ });
82
+ it('reports SSR as unsupported without accessing the DOM', () => {
83
+ const summary = createWebMcpEnvironmentSummary({
84
+ globalObject: {},
85
+ });
86
+ expect(summary.supported).toBe(false);
87
+ expect(summary.origin).toBe('unknown');
88
+ expect(summary.checks).toContainEqual(expect.objectContaining({ id: 'origin-trial', status: 'muted' }));
89
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-blockers.d.ts","sourceRoot":"","sources":["../src/workflow-blockers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AACnD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAE1D,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACjC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAClC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAClC;AAED,MAAM,WAAW,uBAAuB;IACtC,cAAc,CAAC,EAAE,0BAA0B,GAAG,SAAS,CAAC;IACxD,aAAa,CAAC,EAAE,MAAM,qBAAqB,EAAE,CAAC;IAC9C,wBAAwB,CAAC,EAAE,MAAM,sBAAsB,EAAE,CAAC;IAC1D,cAAc,CAAC,EAAE,MAAM,YAAY,EAAE,CAAC;IACtC,YAAY,CAAC,EAAE,MAAM,kBAAkB,EAAE,CAAC;IAC1C,eAAe,CAAC,EAAE,MAAM;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC/D,YAAY,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC9C;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,KAAK,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,OAAO,CAAC;QACnB,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC,CAAC;IACH,KAAK,EAAE,qBAAqB,EAAE,CAAC;IAC/B,gBAAgB,EAAE,sBAAsB,EAAE,CAAC;IAC3C,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,SAAS,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IACnD,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxC;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,uBAAuB,EAChC,IAAI,SAA0B,GAC7B,oBAAoB,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,sBAAsB,CAAC,CAwCrE;AAED,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,kBAAkB,GACvB,qBAAqB,CAWvB;AAED,wBAAgB,wBAAwB,CACtC,IAAI,GAAE,UAAyE,GAC9E,sBAAsB,EAAE,CAgB1B"}
1
+ {"version":3,"file":"workflow-blockers.d.ts","sourceRoot":"","sources":["../src/workflow-blockers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AACnD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAE1D,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACjC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAClC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAClC;AAED,MAAM,WAAW,uBAAuB;IACtC,cAAc,CAAC,EAAE,0BAA0B,GAAG,SAAS,CAAC;IACxD,aAAa,CAAC,EAAE,MAAM,qBAAqB,EAAE,CAAC;IAC9C,wBAAwB,CAAC,EAAE,MAAM,sBAAsB,EAAE,CAAC;IAC1D,cAAc,CAAC,EAAE,MAAM,YAAY,EAAE,CAAC;IACtC,YAAY,CAAC,EAAE,MAAM,kBAAkB,EAAE,CAAC;IAC1C,eAAe,CAAC,EAAE,MAAM;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC/D,YAAY,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC9C;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,KAAK,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,OAAO,CAAC;QACnB,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC,CAAC;IACH,KAAK,EAAE,qBAAqB,EAAE,CAAC;IAC/B,gBAAgB,EAAE,sBAAsB,EAAE,CAAC;IAC3C,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,SAAS,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IACnD,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxC;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,uBAAuB,EAChC,IAAI,SAA0B,GAC7B,oBAAoB,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,sBAAsB,CAAC,CA4CrE;AAED,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,kBAAkB,GACvB,qBAAqB,CAWvB;AAED,wBAAgB,wBAAwB,CACtC,IAAI,GAAE,UAAyE,GAC9E,sBAAsB,EAAE,CAgB1B"}
@@ -7,7 +7,11 @@ export function createWorkflowBlockersTool(sources, name = 'get_workflow_blocker
7
7
  properties: {},
8
8
  additionalProperties: false,
9
9
  },
10
- annotations: { readOnlyHint: true, untrustedContentHint: true },
10
+ annotations: {
11
+ readOnlyHint: true,
12
+ untrustedContentHint: true,
13
+ debugging: true,
14
+ },
11
15
  execute: () => {
12
16
  const actions = sources.actionProvider?.listActions?.().map((action) => ({
13
17
  actionId: action.actionId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tooluminati/diagnostics",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Runtime diagnostic tool factories for Tooluminati.",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -15,7 +15,7 @@
15
15
  }
16
16
  },
17
17
  "dependencies": {
18
- "@tooluminati/core": "0.1.0"
18
+ "@tooluminati/core": "0.2.0"
19
19
  },
20
20
  "files": [
21
21
  "dist"