@tooluminati/diagnostics 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.
@@ -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,29 +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 = [];
617
- const documentContextStatus = documentContext ? "ok" : supported ? "warn" : "fail";
673
+ const documentContextStatus = (0, import_core.isUsableModelContext)(documentContext) ? "ok" : supported ? "warn" : "fail";
618
674
  checks.push({
619
675
  id: "document.modelContext",
620
676
  label: "document.modelContext",
621
- value: documentContext ? "available" : supported ? "missing; using fallback" : "missing",
677
+ value: (0, import_core.isUsableModelContext)(documentContext) ? "available" : supported ? "missing; using fallback" : "missing",
622
678
  status: documentContextStatus,
623
- ...documentContext ? {} : {
624
- hint: supported ? "No document.modelContext on this page, but WebMCP is available through navigator.modelContext in this Chrome build." : "No document.modelContext on this page. Enable WebMCP in Chrome or attach the Model Context Inspector Extension."
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.'
625
690
  }
626
691
  });
627
692
  checks.push({
@@ -633,6 +698,13 @@ function createWebMcpEnvironmentSummary(options = {}) {
633
698
  hint: "Deprecated navigator.modelContext path detected. Migrate to document.modelContext."
634
699
  } : {}
635
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
+ });
636
708
  const originIsolation = detectOriginIsolationIssue(globalObject);
637
709
  checks.push({
638
710
  id: "origin-isolation",
@@ -655,6 +727,13 @@ function createWebMcpEnvironmentSummary(options = {}) {
655
727
  if (permissionsPolicy.warning) {
656
728
  warnings.push(permissionsPolicy.warning);
657
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
+ });
658
737
  if (toolCount === 0 && supported) {
659
738
  warnings.push("No tools registered yet.");
660
739
  checks.push({
@@ -673,6 +752,8 @@ function createWebMcpEnvironmentSummary(options = {}) {
673
752
  toolCount,
674
753
  origin,
675
754
  usingNavigatorFallback,
755
+ registerToolAvailable,
756
+ consumers: WEBMCP_CONSUMERS,
676
757
  checks,
677
758
  warnings
678
759
  };
@@ -734,7 +815,7 @@ function createWebMcpEnvironmentTool(getSummary, name = "get_webmcp_environment"
734
815
  properties: {},
735
816
  additionalProperties: false
736
817
  },
737
- annotations: { readOnlyHint: true },
818
+ annotations: { readOnlyHint: true, debugging: true },
738
819
  execute: () => getSummary()
739
820
  };
740
821
  }
@@ -749,7 +830,11 @@ function createWorkflowBlockersTool(sources, name = "get_workflow_blockers") {
749
830
  properties: {},
750
831
  additionalProperties: false
751
832
  },
752
- annotations: { readOnlyHint: true, untrustedContentHint: true },
833
+ annotations: {
834
+ readOnlyHint: true,
835
+ untrustedContentHint: true,
836
+ debugging: true
837
+ },
753
838
  execute: () => {
754
839
  const actions = sources.actionProvider?.listActions?.().map((action) => ({
755
840
  actionId: action.actionId,
@@ -1165,6 +1250,7 @@ function filterPanelEvents(events, filter) {
1165
1250
  ClientErrorBuffer,
1166
1251
  TROUBLESHOOTING_GUIDANCE,
1167
1252
  TroubleshootingTimelineBuffer,
1253
+ WEBMCP_DECLARATIVE_FOCUS_STYLES,
1168
1254
  buildTroubleshootingPanelSnapshot,
1169
1255
  computeTroubleshootingPanelState,
1170
1256
  createActionAvailabilityTool,
@@ -1188,13 +1274,16 @@ function filterPanelEvents(events, filter) {
1188
1274
  createWebMcpLifecycleCollector,
1189
1275
  createWorkflowBlockersTool,
1190
1276
  discoverDeclarativeForms,
1277
+ ensureDeclarativeFocusStyles,
1191
1278
  filterPanelEvents,
1192
1279
  formSummaryFromMounted,
1193
1280
  getGuidanceForClientError,
1194
1281
  getGuidanceForEnvironmentCheck,
1195
1282
  getGuidanceForTimelineEvent,
1283
+ isAgentInvokedSubmit,
1196
1284
  isPanelEnabledByDefault,
1197
1285
  isPanelUrlOverrideEnabled,
1286
+ respondWithAgentResult,
1198
1287
  serializeTroubleshootingDiagnostics,
1199
1288
  timelineEventGroup
1200
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,31 +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 = [];
560
- const documentContextStatus = documentContext ? "ok" : supported ? "warn" : "fail";
613
+ const documentContextStatus = isUsableModelContext(documentContext) ? "ok" : supported ? "warn" : "fail";
561
614
  checks.push({
562
615
  id: "document.modelContext",
563
616
  label: "document.modelContext",
564
- value: documentContext ? "available" : supported ? "missing; using fallback" : "missing",
617
+ value: isUsableModelContext(documentContext) ? "available" : supported ? "missing; using fallback" : "missing",
565
618
  status: documentContextStatus,
566
- ...documentContext ? {} : {
567
- hint: supported ? "No document.modelContext on this page, but WebMCP is available through navigator.modelContext in this Chrome build." : "No document.modelContext on this page. Enable WebMCP in Chrome or attach the Model Context Inspector Extension."
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.'
568
630
  }
569
631
  });
570
632
  checks.push({
@@ -576,6 +638,13 @@ function createWebMcpEnvironmentSummary(options = {}) {
576
638
  hint: "Deprecated navigator.modelContext path detected. Migrate to document.modelContext."
577
639
  } : {}
578
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
+ });
579
648
  const originIsolation = detectOriginIsolationIssue(globalObject);
580
649
  checks.push({
581
650
  id: "origin-isolation",
@@ -598,6 +667,13 @@ function createWebMcpEnvironmentSummary(options = {}) {
598
667
  if (permissionsPolicy.warning) {
599
668
  warnings.push(permissionsPolicy.warning);
600
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
+ });
601
677
  if (toolCount === 0 && supported) {
602
678
  warnings.push("No tools registered yet.");
603
679
  checks.push({
@@ -616,6 +692,8 @@ function createWebMcpEnvironmentSummary(options = {}) {
616
692
  toolCount,
617
693
  origin,
618
694
  usingNavigatorFallback,
695
+ registerToolAvailable,
696
+ consumers: WEBMCP_CONSUMERS,
619
697
  checks,
620
698
  warnings
621
699
  };
@@ -677,7 +755,7 @@ function createWebMcpEnvironmentTool(getSummary, name = "get_webmcp_environment"
677
755
  properties: {},
678
756
  additionalProperties: false
679
757
  },
680
- annotations: { readOnlyHint: true },
758
+ annotations: { readOnlyHint: true, debugging: true },
681
759
  execute: () => getSummary()
682
760
  };
683
761
  }
@@ -692,7 +770,11 @@ function createWorkflowBlockersTool(sources, name = "get_workflow_blockers") {
692
770
  properties: {},
693
771
  additionalProperties: false
694
772
  },
695
- annotations: { readOnlyHint: true, untrustedContentHint: true },
773
+ annotations: {
774
+ readOnlyHint: true,
775
+ untrustedContentHint: true,
776
+ debugging: true
777
+ },
696
778
  execute: () => {
697
779
  const actions = sources.actionProvider?.listActions?.().map((action) => ({
698
780
  actionId: action.actionId,
@@ -1107,6 +1189,7 @@ export {
1107
1189
  ClientErrorBuffer,
1108
1190
  TROUBLESHOOTING_GUIDANCE,
1109
1191
  TroubleshootingTimelineBuffer,
1192
+ WEBMCP_DECLARATIVE_FOCUS_STYLES,
1110
1193
  buildTroubleshootingPanelSnapshot,
1111
1194
  computeTroubleshootingPanelState,
1112
1195
  createActionAvailabilityTool,
@@ -1130,13 +1213,16 @@ export {
1130
1213
  createWebMcpLifecycleCollector,
1131
1214
  createWorkflowBlockersTool,
1132
1215
  discoverDeclarativeForms,
1216
+ ensureDeclarativeFocusStyles,
1133
1217
  filterPanelEvents,
1134
1218
  formSummaryFromMounted,
1135
1219
  getGuidanceForClientError,
1136
1220
  getGuidanceForEnvironmentCheck,
1137
1221
  getGuidanceForTimelineEvent,
1222
+ isAgentInvokedSubmit,
1138
1223
  isPanelEnabledByDefault,
1139
1224
  isPanelUrlOverrideEnabled,
1225
+ respondWithAgentResult,
1140
1226
  serializeTroubleshootingDiagnostics,
1141
1227
  timelineEventGroup
1142
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":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,iBAAiB,EAAsB,MAAM,UAAU,CAAC;AAEtE,MAAM,MAAM,4BAA4B,GACpC,cAAc,GACd,eAAe,GACf,cAAc,GACd,gBAAgB,GAChB,gBAAgB,GAChB,gBAAgB,GAChB,mBAAmB,GACnB,YAAY,GACZ,QAAQ,CAAC;AAEb,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,4BAA4B,CAAC;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IAC9C,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACjC;AAED,MAAM,WAAW,wBAAyB,SAAQ,wBAAwB;IACxE,QAAQ,EAAE,cAAc,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAED,MAAM,WAAW,yBAA0B,SAAQ,wBAAwB;IACzE,QAAQ,EAAE,eAAe,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC;AAED,MAAM,WAAW,wBAAyB,SAAQ,wBAAwB;IACxE,QAAQ,EAAE,cAAc,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,0BAA2B,SAAQ,wBAAwB;IAC1E,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,0BAA2B,SAAQ,wBAAwB;IAC1E,QAAQ,EAAE,gBAAgB,GAAG,gBAAgB,GAAG,mBAAmB,CAAC;IACpE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAED,MAAM,WAAW,uBAAwB,SAAQ,wBAAwB;IACvE,QAAQ,EAAE,YAAY,CAAC;IACvB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,mBAAoB,SAAQ,wBAAwB;IACnE,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAED,MAAM,MAAM,oBAAoB,GAC5B,wBAAwB,GACxB,yBAAyB,GACzB,wBAAwB,GACxB,0BAA0B,GAC1B,0BAA0B,GAC1B,uBAAuB,GACvB,mBAAmB,CAAC;AAExB,MAAM,WAAW,oCAAoC;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,oBAAoB,CAAC;CAChE;AAkCD,MAAM,MAAM,yBAAyB,GACjC,IAAI,CAAC,wBAAwB,EAAE,IAAI,GAAG,WAAW,CAAC,GAClD,IAAI,CAAC,yBAAyB,EAAE,IAAI,GAAG,WAAW,CAAC,GACnD,IAAI,CAAC,wBAAwB,EAAE,IAAI,GAAG,WAAW,CAAC,GAClD,IAAI,CAAC,0BAA0B,EAAE,IAAI,GAAG,WAAW,CAAC,GACpD,IAAI,CAAC,0BAA0B,EAAE,IAAI,GAAG,WAAW,CAAC,GACpD,IAAI,CAAC,uBAAuB,EAAE,IAAI,GAAG,WAAW,CAAC,GACjD,IAAI,CAAC,mBAAmB,EAAE,IAAI,GAAG,WAAW,CAAC,CAAC;AAElD,qBAAa,6BAA6B;IACxC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA8B;IACrD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAEE;gBAEd,OAAO,GAAE,oCAAoC,GAAG,MAAW;IAWvE,IAAI,CACF,KAAK,EAAE,yBAAyB,GAAG;QACjC,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GACA,oBAAoB;IAavB,IAAI,CAAC,OAAO,CAAC,EAAE;QACb,UAAU,CAAC,EAAE,4BAA4B,EAAE,CAAC;QAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GAAG,oBAAoB,EAAE;IAuB1B,OAAO,CAAC,MAAM,GAAE,oBAAoB,EAAgB,GAAG;QACrD,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACpC;IAQD,KAAK,IAAI,IAAI;CAGd;AAED,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,6BAA6B,CAAC;IACtC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAKD,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,0BAA0B,GAClC,MAAM,IAAI,CAqEZ;AAUD,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,iBAAiB,EACzB,QAAQ,EAAE,6BAA6B,GACtC,MAAM,IAAI,CAoBZ;AAED,MAAM,WAAW,+BAA+B;IAC9C,MAAM,EAAE,6BAA6B,CAAC;IACtC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,+BAA+B,GACvC,MAAM,IAAI,CAgFZ;AAED,MAAM,WAAW,gCAAgC;IAC/C,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,iCAAiC,CAC/C,MAAM,EAAE,6BAA6B,EACrC,IAAI,SAAiC,GACpC,oBAAoB,CACrB,gCAAgC,EAChC;IACE,MAAM,EAAE,oBAAoB,EAAE,CAAC;IAC/B,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC;CAChE,CACF,CA6DA"}
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,CAgH1B;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.1",
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.1"
18
+ "@tooluminati/core": "0.2.0"
19
19
  },
20
20
  "files": [
21
21
  "dist"