@tooluminati/react-troubleshooting 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/LICENSE +21 -0
  2. package/dist/WebMcpErrorBoundary.d.ts +8 -0
  3. package/dist/WebMcpErrorBoundary.d.ts.map +1 -0
  4. package/dist/WebMcpErrorBoundary.js +29 -0
  5. package/dist/WebMcpTroubleshootingContext.d.ts +12 -0
  6. package/dist/WebMcpTroubleshootingContext.d.ts.map +1 -0
  7. package/dist/WebMcpTroubleshootingContext.js +9 -0
  8. package/dist/WebMcpTroubleshootingPanel.d.ts +9 -0
  9. package/dist/WebMcpTroubleshootingPanel.d.ts.map +1 -0
  10. package/dist/WebMcpTroubleshootingPanel.js +170 -0
  11. package/dist/WebMcpTroubleshootingProvider.d.ts +23 -0
  12. package/dist/WebMcpTroubleshootingProvider.d.ts.map +1 -0
  13. package/dist/WebMcpTroubleshootingProvider.js +106 -0
  14. package/dist/declarative-form.d.ts +23 -0
  15. package/dist/declarative-form.d.ts.map +1 -0
  16. package/dist/declarative-form.js +33 -0
  17. package/dist/index.cjs +833 -0
  18. package/dist/index.d.ts +11 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +822 -0
  21. package/dist/panel-visibility.d.ts +8 -0
  22. package/dist/panel-visibility.d.ts.map +1 -0
  23. package/dist/panel-visibility.js +23 -0
  24. package/dist/useFormSubmitBlockers.d.ts +11 -0
  25. package/dist/useFormSubmitBlockers.d.ts.map +1 -0
  26. package/dist/useFormSubmitBlockers.js +35 -0
  27. package/dist/useTanStackQueryWebMcpTools.d.ts +9 -0
  28. package/dist/useTanStackQueryWebMcpTools.d.ts.map +1 -0
  29. package/dist/useTanStackQueryWebMcpTools.js +16 -0
  30. package/dist/useTroubleshootingPanel.d.ts +14 -0
  31. package/dist/useTroubleshootingPanel.d.ts.map +1 -0
  32. package/dist/useTroubleshootingPanel.js +29 -0
  33. package/dist/webmcp-declarative-attributes.d.ts +20 -0
  34. package/dist/webmcp-declarative-attributes.d.ts.map +1 -0
  35. package/dist/webmcp-declarative-attributes.js +2 -0
  36. package/package.json +67 -0
package/dist/index.cjs ADDED
@@ -0,0 +1,833 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ WebMcpErrorBoundary: () => WebMcpErrorBoundary,
24
+ WebMcpForm: () => WebMcpForm,
25
+ WebMcpInput: () => WebMcpInput,
26
+ WebMcpSelect: () => WebMcpSelect,
27
+ WebMcpTextarea: () => WebMcpTextarea,
28
+ WebMcpTroubleshootingContext: () => WebMcpTroubleshootingContext,
29
+ WebMcpTroubleshootingPanel: () => WebMcpTroubleshootingPanel,
30
+ WebMcpTroubleshootingProvider: () => WebMcpTroubleshootingProvider,
31
+ createFormSubmitBlockersProvider: () => createFormSubmitBlockersProvider,
32
+ getPanelVisibilityController: () => getPanelVisibilityController,
33
+ hideWebMcpTroubleshootingPanel: () => hideWebMcpTroubleshootingPanel,
34
+ resetPanelVisibilityController: () => resetPanelVisibilityController,
35
+ showWebMcpTroubleshootingPanel: () => showWebMcpTroubleshootingPanel,
36
+ toggleWebMcpTroubleshootingPanel: () => toggleWebMcpTroubleshootingPanel,
37
+ useAgentInvokedSubmit: () => useAgentInvokedSubmit,
38
+ useDeclarativeFormToolEvents: () => useDeclarativeFormToolEvents,
39
+ useFormSubmitBlockers: () => useFormSubmitBlockers,
40
+ useTanStackQueryWebMcpTools: () => useTanStackQueryWebMcpTools,
41
+ useTroubleshootingPanel: () => useTroubleshootingPanel,
42
+ useTroubleshootingPanelVisibility: () => useTroubleshootingPanelVisibility,
43
+ useWebMcpTroubleshootingContext: () => useWebMcpTroubleshootingContext,
44
+ wirePanelVisibilityController: () => wirePanelVisibilityController
45
+ });
46
+ module.exports = __toCommonJS(index_exports);
47
+
48
+ // src/webmcp-declarative-attributes.ts
49
+ var import_react = require("react");
50
+
51
+ // src/WebMcpTroubleshootingProvider.tsx
52
+ var import_react4 = require("react");
53
+ var import_diagnostics3 = require("@tooluminati/diagnostics");
54
+ var import_react5 = require("@tooluminati/react");
55
+
56
+ // src/WebMcpTroubleshootingContext.tsx
57
+ var import_react2 = require("react");
58
+ var WebMcpTroubleshootingContext = (0, import_react2.createContext)(null);
59
+ function useWebMcpTroubleshootingContext() {
60
+ const value = (0, import_react2.useContext)(WebMcpTroubleshootingContext);
61
+ if (!value) {
62
+ throw new Error(
63
+ "useWebMcpTroubleshootingContext requires WebMcpTroubleshootingProvider."
64
+ );
65
+ }
66
+ return value;
67
+ }
68
+
69
+ // src/WebMcpTroubleshootingPanel.tsx
70
+ var import_react3 = require("react");
71
+ var import_diagnostics = require("@tooluminati/diagnostics");
72
+ var import_jsx_runtime = require("react/jsx-runtime");
73
+ var PALETTE = {
74
+ surface: "#0a0e1a",
75
+ navy: "#17316A",
76
+ amber: "#FECD10",
77
+ cyan: "#0AADF2",
78
+ red: "#FF5C6C"
79
+ };
80
+ var positionStyle = {
81
+ br: { right: "26px", bottom: "26px" },
82
+ bl: { left: "26px", bottom: "26px" },
83
+ tr: { right: "26px", top: "26px" },
84
+ tl: { left: "26px", top: "26px" }
85
+ };
86
+ function WebMcpTroubleshootingPanel({
87
+ position = "br",
88
+ startCollapsed,
89
+ onCopyDiagnostics
90
+ }) {
91
+ const { viewModel, visibility, isPanelEnabled } = useWebMcpTroubleshootingContext();
92
+ const [snapshot, setSnapshot] = (0, import_react3.useState)(
93
+ () => viewModel.refresh()
94
+ );
95
+ const [filter, setFilter] = (0, import_react3.useState)("all");
96
+ const [openChecks, setOpenChecks] = (0, import_react3.useState)({});
97
+ const [openEvents, setOpenEvents] = (0, import_react3.useState)({});
98
+ const [openErrors, setOpenErrors] = (0, import_react3.useState)({});
99
+ const [copied, setCopied] = (0, import_react3.useState)(false);
100
+ const [spinning, setSpinning] = (0, import_react3.useState)(false);
101
+ (0, import_react3.useEffect)(() => {
102
+ if (startCollapsed) {
103
+ visibility.setCollapsed(true);
104
+ }
105
+ }, [startCollapsed, visibility]);
106
+ (0, import_react3.useEffect)(() => {
107
+ const refresh2 = () => setSnapshot(viewModel.refresh());
108
+ refresh2();
109
+ const unsubVm = viewModel.subscribe(refresh2);
110
+ const unsubVis = visibility.subscribe(refresh2);
111
+ return () => {
112
+ unsubVm();
113
+ unsubVis();
114
+ };
115
+ }, [viewModel, visibility]);
116
+ const filteredEvents = (0, import_react3.useMemo)(
117
+ () => (0, import_diagnostics.filterPanelEvents)(snapshot.events, filter),
118
+ [snapshot.events, filter]
119
+ );
120
+ if (!isPanelEnabled || !visibility.visible) {
121
+ return null;
122
+ }
123
+ const pos = positionStyle[position];
124
+ const supportColor = snapshot.supported ? PALETTE.cyan : PALETTE.red;
125
+ const collapsed = visibility.collapsed;
126
+ const refresh = () => {
127
+ setSpinning(true);
128
+ setSnapshot(viewModel.refresh());
129
+ window.setTimeout(() => setSpinning(false), 650);
130
+ };
131
+ const copyDiagnostics = async () => {
132
+ const json = (0, import_diagnostics.serializeTroubleshootingDiagnostics)(snapshot);
133
+ if (onCopyDiagnostics) {
134
+ onCopyDiagnostics(json);
135
+ } else if (navigator.clipboard) {
136
+ await navigator.clipboard.writeText(json);
137
+ }
138
+ setCopied(true);
139
+ window.setTimeout(() => setCopied(false), 1500);
140
+ };
141
+ if (collapsed) {
142
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
143
+ "button",
144
+ {
145
+ type: "button",
146
+ "aria-label": "Expand WebMCP troubleshooting panel",
147
+ "data-testid": "webmcp-troubleshooting-badge",
148
+ onClick: () => visibility.setCollapsed(false),
149
+ style: {
150
+ position: "fixed",
151
+ ...pos,
152
+ zIndex: 99990,
153
+ display: "flex",
154
+ alignItems: "center",
155
+ gap: 11,
156
+ padding: "11px 15px 11px 13px",
157
+ background: "#0d1322",
158
+ border: "1px solid #1f2940",
159
+ borderRadius: 13,
160
+ cursor: "pointer",
161
+ boxShadow: "0 14px 40px rgba(0,0,0,.5)",
162
+ fontFamily: "'IBM Plex Sans', system-ui, sans-serif"
163
+ },
164
+ children: [
165
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BrandMark, {}),
166
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: { display: "flex", flexDirection: "column", lineHeight: 1.15 }, children: [
167
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: 12, fontWeight: 600, color: "#e7ecf6" }, children: "WebMCP" }),
168
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
169
+ "span",
170
+ {
171
+ style: {
172
+ fontFamily: "'IBM Plex Mono', monospace",
173
+ fontSize: 10,
174
+ color: supportColor
175
+ },
176
+ children: snapshot.supported ? "supported" : "unsupported"
177
+ }
178
+ )
179
+ ] }),
180
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
181
+ "span",
182
+ {
183
+ style: {
184
+ display: "flex",
185
+ alignItems: "center",
186
+ gap: 6,
187
+ paddingLeft: 11,
188
+ marginLeft: 3,
189
+ borderLeft: "1px solid #20293f"
190
+ },
191
+ children: [
192
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
193
+ "span",
194
+ {
195
+ style: {
196
+ fontFamily: "'IBM Plex Mono', monospace",
197
+ fontSize: 12,
198
+ color: "#aeb7cb"
199
+ },
200
+ children: snapshot.toolCount
201
+ }
202
+ ),
203
+ snapshot.issueCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
204
+ "span",
205
+ {
206
+ style: {
207
+ width: 8,
208
+ height: 8,
209
+ borderRadius: "50%",
210
+ background: snapshot.errors.length > 0 ? PALETTE.red : PALETTE.amber
211
+ }
212
+ }
213
+ ) : null
214
+ ]
215
+ }
216
+ )
217
+ ]
218
+ }
219
+ );
220
+ }
221
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
222
+ "div",
223
+ {
224
+ "aria-label": "WebMCP troubleshooting panel",
225
+ "data-testid": "webmcp-troubleshooting-panel",
226
+ style: {
227
+ position: "fixed",
228
+ ...pos,
229
+ zIndex: 99990,
230
+ width: 412,
231
+ maxHeight: "calc(100vh - 52px)",
232
+ display: "flex",
233
+ flexDirection: "column",
234
+ background: PALETTE.surface,
235
+ border: "1px solid #1c2438",
236
+ borderRadius: 15,
237
+ boxShadow: "0 26px 70px rgba(0,0,0,.62)",
238
+ overflow: "hidden",
239
+ fontFamily: "'IBM Plex Sans', system-ui, sans-serif",
240
+ color: "#eef2fa"
241
+ },
242
+ children: [
243
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
244
+ "header",
245
+ {
246
+ style: {
247
+ display: "flex",
248
+ alignItems: "center",
249
+ gap: 11,
250
+ padding: "13px 14px",
251
+ borderBottom: "1px solid #161d2e"
252
+ },
253
+ children: [
254
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BrandMark, {}),
255
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { marginRight: "auto", lineHeight: 1.2 }, children: [
256
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: 13.5, fontWeight: 600 }, children: "WebMCP Troubleshooting" }),
257
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
258
+ "div",
259
+ {
260
+ style: {
261
+ fontFamily: "'IBM Plex Mono', monospace",
262
+ fontSize: 9.5,
263
+ letterSpacing: 1.6,
264
+ color: "#5f6a82",
265
+ textTransform: "uppercase"
266
+ },
267
+ children: "Tooluminati \xB7 dev panel"
268
+ }
269
+ )
270
+ ] }),
271
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PanelButton, { title: "Re-run checks", onClick: refresh, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { display: "inline-block", animation: spinning ? "tlmSpin .65s linear" : "none" }, children: "\u27F3" }) }),
272
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PanelButton, { onClick: () => void copyDiagnostics(), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontFamily: "'IBM Plex Mono', monospace", fontSize: 11, color: copied ? PALETTE.cyan : "#9aa5bd" }, children: copied ? "Copied \u2713" : "Copy JSON" }) }),
273
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PanelButton, { title: "Minimize", onClick: () => visibility.setCollapsed(true), children: "\u2013" })
274
+ ]
275
+ }
276
+ ),
277
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
278
+ "div",
279
+ {
280
+ style: {
281
+ display: "grid",
282
+ gridTemplateColumns: "1fr 1fr 1fr",
283
+ gap: 1,
284
+ background: "#161d2e"
285
+ },
286
+ children: [
287
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StatTile, { label: "WebMCP", value: snapshot.supported ? "Supported" : "Unsupported", color: supportColor }),
288
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StatTile, { label: "Tools", value: String(snapshot.toolCount), color: snapshot.toolCount > 0 ? "#eef2fa" : PALETTE.amber }),
289
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StatTile, { label: "Issues", value: String(snapshot.issueCount), color: snapshot.errors.length ? PALETTE.red : snapshot.issueCount ? PALETTE.amber : PALETTE.cyan })
290
+ ]
291
+ }
292
+ ),
293
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { overflow: "auto", flex: 1, minHeight: 0 }, children: [
294
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Section, { title: "Environment", children: snapshot.checks.map((check) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
295
+ Row,
296
+ {
297
+ open: openChecks[check.id] ?? false,
298
+ onToggle: () => setOpenChecks((s) => ({ ...s, [check.id]: !s[check.id] })),
299
+ hint: check.guidance,
300
+ label: check.label,
301
+ value: check.value,
302
+ status: check.status
303
+ },
304
+ check.id
305
+ )) }),
306
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Section, { title: "Timeline", meta: `${snapshot.events.length} captured`, children: [
307
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "flex", flexWrap: "wrap", gap: 6, padding: "0 12px 8px" }, children: ["all", "failures", "blocked", "tools", "nav"].map((chip) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
308
+ "button",
309
+ {
310
+ type: "button",
311
+ onClick: () => setFilter(chip),
312
+ style: {
313
+ fontFamily: "'IBM Plex Mono', monospace",
314
+ fontSize: 10.5,
315
+ padding: "4px 9px",
316
+ borderRadius: 20,
317
+ cursor: "pointer",
318
+ border: `1px solid ${filter === chip ? PALETTE.cyan : "#1f2840"}`,
319
+ background: filter === chip ? "rgba(10,173,242,.13)" : "#0d1322",
320
+ color: filter === chip ? "#5EC8F7" : "#8893a8"
321
+ },
322
+ children: chip
323
+ },
324
+ chip
325
+ )) }),
326
+ filteredEvents.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EmptyRow, { label: snapshot.events.length === 0 ? "No timeline activity yet" : "No events in this filter" }) : filteredEvents.map((event) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
327
+ Row,
328
+ {
329
+ open: openEvents[event.id] ?? false,
330
+ onToggle: () => setOpenEvents((s) => ({ ...s, [event.id]: !s[event.id] })),
331
+ hint: event.detail ?? event.guidance,
332
+ meta: event.metadata ? JSON.stringify(event.metadata, null, 2) : void 0,
333
+ label: event.title,
334
+ value: event.time,
335
+ tag: event.category.slice(0, 4).toUpperCase()
336
+ },
337
+ event.id
338
+ ))
339
+ ] }),
340
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Section, { title: "Client Errors", meta: snapshot.errors.length ? `${snapshot.errors.length} captured` : "clean", children: snapshot.errors.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EmptyRow, { label: "No errors captured this session", ok: true }) : snapshot.errors.map((error) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
341
+ Row,
342
+ {
343
+ open: openErrors[error.id] ?? false,
344
+ onToggle: () => setOpenErrors((s) => ({ ...s, [error.id]: !s[error.id] })),
345
+ hint: error.guidance,
346
+ meta: error.stack,
347
+ label: error.message,
348
+ value: error.time,
349
+ tag: "ERR",
350
+ error: true
351
+ },
352
+ error.id
353
+ )) })
354
+ ] }),
355
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
356
+ "footer",
357
+ {
358
+ style: {
359
+ display: "flex",
360
+ alignItems: "center",
361
+ gap: 8,
362
+ padding: "9px 14px",
363
+ borderTop: "1px solid #161d2e",
364
+ background: "#0c1120"
365
+ },
366
+ children: [
367
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { width: 6, height: 6, borderRadius: "50%", background: PALETTE.cyan } }),
368
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: { fontFamily: "'IBM Plex Mono', monospace", fontSize: 10.5, color: "#6b768c" }, children: [
369
+ "Live \xB7 ",
370
+ snapshot.panelState
371
+ ] })
372
+ ]
373
+ }
374
+ ),
375
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: `@keyframes tlmSpin { to { transform: rotate(360deg); } }` })
376
+ ]
377
+ }
378
+ );
379
+ }
380
+ function BrandMark() {
381
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: { position: "relative", width: 26, height: 26, display: "inline-flex", alignItems: "center", justifyContent: "center" }, children: [
382
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { width: 0, height: 0, borderLeft: "13px solid transparent", borderRight: "13px solid transparent", borderBottom: "22px solid #17316A", position: "absolute", top: 1 } }),
383
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { position: "relative", width: 7, height: 7, borderRadius: "50%", background: "#FECD10", marginTop: 6, boxShadow: "0 0 8px #FECD10" } })
384
+ ] });
385
+ }
386
+ function PanelButton({ children, onClick, title }) {
387
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", title, onClick, style: { display: "inline-flex", alignItems: "center", justifyContent: "center", minWidth: 30, height: 30, borderRadius: 8, background: "#121a2b", border: "1px solid #1f2840", color: "#9aa5bd", cursor: "pointer" }, children });
388
+ }
389
+ function StatTile({ label, value, color }) {
390
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { background: "#0a0e1a", padding: "12px 13px" }, children: [
391
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontFamily: "'IBM Plex Mono', monospace", fontSize: 9.5, letterSpacing: 1, color: "#5f6a82", textTransform: "uppercase" }, children: label }),
392
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: 14, fontWeight: 600, color }, children: value })
393
+ ] });
394
+ }
395
+ function Section({ title, meta, children }) {
396
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { paddingBottom: 8 }, children: [
397
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { padding: "13px 14px 6px", display: "flex", alignItems: "center", gap: 8 }, children: [
398
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontFamily: "'IBM Plex Mono', monospace", fontSize: 10, letterSpacing: 1.5, color: "#7b8aa6", textTransform: "uppercase", fontWeight: 600 }, children: title }),
399
+ meta ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontFamily: "'IBM Plex Mono', monospace", fontSize: 10, color: "#4f5870" }, children: meta }) : null
400
+ ] }),
401
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { padding: "0 12px" }, children })
402
+ ] });
403
+ }
404
+ function Row({
405
+ label,
406
+ value,
407
+ hint,
408
+ meta,
409
+ tag,
410
+ status,
411
+ open,
412
+ onToggle,
413
+ error
414
+ }) {
415
+ const expandable = Boolean(hint || meta);
416
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { borderRadius: 8, overflow: "hidden", marginBottom: 3, background: open ? "#0e1424" : error ? "rgba(255,92,108,.05)" : "#0b0f1c", borderLeft: error ? `2px solid #FF5C6C` : void 0 }, children: [
417
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { type: "button", onClick: expandable ? onToggle : void 0, style: { width: "100%", display: "flex", alignItems: "center", gap: 9, padding: "7px 10px", background: "transparent", border: 0, cursor: expandable ? "pointer" : "default", color: "inherit", textAlign: "left" }, children: [
418
+ tag ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontFamily: "'IBM Plex Mono', monospace", fontSize: 8.5, fontWeight: 600, padding: "2px 5px", borderRadius: 4, color: error ? "#FF8088" : "#5EC8F7", background: error ? "rgba(255,92,108,.12)" : "rgba(10,173,242,.13)" }, children: tag }) : null,
419
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: 12, flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: label }),
420
+ value ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontFamily: "'IBM Plex Mono', monospace", fontSize: 10, color: status === "warn" ? "#FFD86B" : status === "fail" ? "#FF8088" : "#58627a" }, children: value }) : null,
421
+ expandable ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontFamily: "'IBM Plex Mono', monospace", fontSize: 11, color: "#586279" }, children: open ? "\u25BE" : "\u25B8" }) : null
422
+ ] }),
423
+ open && hint ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { padding: "0 12px 11px 36px", fontSize: 11.5, lineHeight: 1.55, color: "#9aa5bd" }, children: hint }) : null,
424
+ open && meta ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("pre", { style: { margin: "0 12px 11px", fontFamily: "'IBM Plex Mono', monospace", fontSize: 10.5, color: "#6b768c", background: "#070b14", border: "1px solid #161d2e", borderRadius: 6, padding: "7px 9px", whiteSpace: "pre-wrap" }, children: meta }) : null
425
+ ] });
426
+ }
427
+ function EmptyRow({ label, ok }) {
428
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { padding: "12px 10px", fontSize: 12, color: "#586279", fontFamily: "'IBM Plex Mono', monospace" }, children: [
429
+ ok ? "\u2713 " : "",
430
+ label
431
+ ] });
432
+ }
433
+
434
+ // src/panel-visibility.ts
435
+ var import_diagnostics2 = require("@tooluminati/diagnostics");
436
+ var controller;
437
+ function getPanelVisibilityController() {
438
+ if (!controller) {
439
+ controller = (0, import_diagnostics2.createTroubleshootingPanelVisibilityController)();
440
+ }
441
+ return controller;
442
+ }
443
+ function wirePanelVisibilityController(next) {
444
+ controller = next;
445
+ }
446
+ function showWebMcpTroubleshootingPanel() {
447
+ getPanelVisibilityController().show();
448
+ }
449
+ function hideWebMcpTroubleshootingPanel() {
450
+ getPanelVisibilityController().hide();
451
+ }
452
+ function toggleWebMcpTroubleshootingPanel() {
453
+ getPanelVisibilityController().toggle();
454
+ }
455
+ function resetPanelVisibilityController() {
456
+ controller = void 0;
457
+ }
458
+
459
+ // src/WebMcpTroubleshootingProvider.tsx
460
+ var import_jsx_runtime2 = require("react/jsx-runtime");
461
+ function WebMcpTroubleshootingInner({
462
+ children,
463
+ timeline,
464
+ errors,
465
+ mountedForms,
466
+ trackFetchFailures,
467
+ panel,
468
+ panelEnabled,
469
+ registryRef
470
+ }) {
471
+ const registry = (0, import_react5.useWebMcpRegistry)();
472
+ (0, import_react4.useEffect)(() => {
473
+ registryRef.current = registry;
474
+ }, [registry, registryRef]);
475
+ const visibility = (0, import_react4.useMemo)(() => {
476
+ const controller2 = getPanelVisibilityController();
477
+ wirePanelVisibilityController(controller2);
478
+ if (panel?.startCollapsed) {
479
+ controller2.setCollapsed(true);
480
+ }
481
+ return controller2;
482
+ }, [panel?.startCollapsed]);
483
+ const viewModel = (0, import_react4.useMemo)(
484
+ () => (0, import_diagnostics3.createTroubleshootingPanelViewModel)(
485
+ {
486
+ timeline,
487
+ errors,
488
+ environment: () => (0, import_diagnostics3.createWebMcpEnvironmentSummary)({ registry }),
489
+ registry
490
+ },
491
+ {
492
+ pollMs: panel?.pollMs ?? 2e3,
493
+ registry,
494
+ ...panel?.eventLimit !== void 0 ? { eventLimit: panel.eventLimit } : {}
495
+ }
496
+ ),
497
+ [timeline, errors, registry, panel?.eventLimit, panel?.pollMs]
498
+ );
499
+ (0, import_react4.useEffect)(() => {
500
+ const cleanups = [
501
+ (0, import_diagnostics3.createErrorCollector)({ buffer: errors }),
502
+ (0, import_diagnostics3.createTimelineFromErrorBuffer)(errors, timeline),
503
+ (0, import_diagnostics3.createWebMcpLifecycleCollector)({ buffer: timeline })
504
+ ];
505
+ if (trackFetchFailures) {
506
+ cleanups.push((0, import_diagnostics3.createFetchFailureTracker)({ buffer: timeline }));
507
+ }
508
+ return () => {
509
+ for (const cleanup of cleanups) {
510
+ cleanup();
511
+ }
512
+ viewModel.dispose();
513
+ };
514
+ }, [errors, timeline, trackFetchFailures, viewModel]);
515
+ const shouldRenderPanel = panelEnabled && panel?.render !== false && (panel?.render === true || panel?.render === "auto" || panel?.render === void 0);
516
+ const contextValue = (0, import_react4.useMemo)(
517
+ () => ({
518
+ timeline,
519
+ errors,
520
+ mountedForms,
521
+ viewModel,
522
+ visibility,
523
+ isPanelEnabled: panelEnabled
524
+ }),
525
+ [timeline, errors, mountedForms, viewModel, visibility, panelEnabled]
526
+ );
527
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(WebMcpTroubleshootingContext.Provider, { value: contextValue, children: [
528
+ children,
529
+ shouldRenderPanel ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
530
+ WebMcpTroubleshootingPanel,
531
+ {
532
+ position: panel?.position ?? "br",
533
+ ...panel?.startCollapsed !== void 0 ? { startCollapsed: panel.startCollapsed } : {},
534
+ ...panel?.eventLimit !== void 0 ? { eventLimit: panel.eventLimit } : {},
535
+ pollMs: panel?.pollMs ?? 2e3
536
+ }
537
+ ) : null
538
+ ] });
539
+ }
540
+ function WebMcpTroubleshootingProvider({
541
+ children,
542
+ actionProvider,
543
+ querySummaries,
544
+ trackFetchFailures = true,
545
+ panel,
546
+ tools = [],
547
+ extraTools = [],
548
+ ...providerProps
549
+ }) {
550
+ const timeline = (0, import_react4.useMemo)(() => new import_diagnostics3.TroubleshootingTimelineBuffer(), []);
551
+ const errors = (0, import_react4.useMemo)(
552
+ () => new import_diagnostics3.ClientErrorBuffer({ includeStacks: true }),
553
+ []
554
+ );
555
+ const mountedForms = (0, import_react4.useMemo)(() => (0, import_diagnostics3.createMountedFormsRegistry)(), []);
556
+ const registryRef = (0, import_react4.useRef)(void 0);
557
+ const actionProviderRef = (0, import_react4.useRef)(actionProvider);
558
+ const querySummariesRef = (0, import_react4.useRef)(querySummaries);
559
+ actionProviderRef.current = actionProvider;
560
+ querySummariesRef.current = querySummaries;
561
+ (0, import_react4.useEffect)(() => () => resetPanelVisibilityController(), []);
562
+ const panelEnabled = (0, import_diagnostics3.isPanelEnabledByDefault)(panel?.enabled) || (0, import_diagnostics3.isPanelUrlOverrideEnabled)(panel?.allowUrlOverride);
563
+ const liveActionProvider = (0, import_react4.useMemo)(
564
+ () => ({
565
+ getActionAvailability: (actionId) => actionProviderRef.current?.getActionAvailability(actionId),
566
+ listActions: () => actionProviderRef.current?.listActions?.() ?? []
567
+ }),
568
+ []
569
+ );
570
+ const diagnosticTools = (0, import_react4.useMemo)(
571
+ () => [
572
+ (0, import_diagnostics3.createTroubleshootingTimelineTool)(timeline),
573
+ (0, import_diagnostics3.createWebMcpEnvironmentTool)(
574
+ () => (0, import_diagnostics3.createWebMcpEnvironmentSummary)({ registry: registryRef.current })
575
+ ),
576
+ (0, import_diagnostics3.createRecentClientErrorsTool)(errors),
577
+ (0, import_diagnostics3.createMountedFormsSummaryTool)(mountedForms),
578
+ (0, import_diagnostics3.createWorkflowBlockersTool)({
579
+ ...actionProvider ? { actionProvider: liveActionProvider } : {},
580
+ formSummaries: () => mountedForms.list().map(import_diagnostics3.formSummaryFromMounted),
581
+ declarativeFormSummaries: () => (0, import_diagnostics3.discoverDeclarativeForms)(),
582
+ recentErrors: () => errors.list(),
583
+ querySummaries: () => querySummariesRef.current?.() ?? []
584
+ }),
585
+ ...actionProvider ? [
586
+ (0, import_diagnostics3.createActionAvailabilityTool)(liveActionProvider),
587
+ (0, import_diagnostics3.createListActionsTool)(liveActionProvider)
588
+ ] : [],
589
+ ...tools,
590
+ ...extraTools
591
+ ],
592
+ [timeline, errors, mountedForms, actionProvider, liveActionProvider, tools, extraTools]
593
+ );
594
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react5.WebMcpProvider, { ...providerProps, tools: diagnosticTools, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
595
+ WebMcpTroubleshootingInner,
596
+ {
597
+ timeline,
598
+ errors,
599
+ mountedForms,
600
+ trackFetchFailures,
601
+ panelEnabled,
602
+ registryRef,
603
+ ...actionProvider ? { actionProvider } : {},
604
+ ...querySummaries ? { querySummaries } : {},
605
+ ...panel ? { panel } : {},
606
+ children
607
+ }
608
+ ) });
609
+ }
610
+
611
+ // src/WebMcpErrorBoundary.tsx
612
+ var import_react6 = require("react");
613
+ var import_jsx_runtime3 = require("react/jsx-runtime");
614
+ var Boundary = class extends import_react6.Component {
615
+ state = { hasError: false };
616
+ static getDerivedStateFromError() {
617
+ return { hasError: true };
618
+ }
619
+ componentDidCatch(error, info) {
620
+ this.props.errors.push({
621
+ message: error.message,
622
+ source: this.props.source ?? info.componentStack?.split("\n")[1]?.trim() ?? "react",
623
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
624
+ ...error.stack ? { stack: error.stack } : {}
625
+ });
626
+ }
627
+ render() {
628
+ if (this.state.hasError) {
629
+ return this.props.fallback ?? null;
630
+ }
631
+ return this.props.children;
632
+ }
633
+ };
634
+ function WebMcpErrorBoundary({
635
+ children,
636
+ fallback,
637
+ source
638
+ }) {
639
+ const { errors, timeline } = useWebMcpTroubleshootingContext();
640
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
641
+ Boundary,
642
+ {
643
+ errors,
644
+ timeline,
645
+ fallback,
646
+ ...source ? { source } : {},
647
+ children
648
+ }
649
+ );
650
+ }
651
+
652
+ // src/useTanStackQueryWebMcpTools.ts
653
+ var import_react7 = require("react");
654
+ var import_react8 = require("@tooluminati/react");
655
+ var import_state = require("@tooluminati/state");
656
+ function useTanStackQueryWebMcpTools(queryClient, options) {
657
+ const {
658
+ allowKeys,
659
+ includeDataShape,
660
+ includeData,
661
+ name
662
+ } = options;
663
+ const tool = (0, import_react7.useMemo)(() => {
664
+ return (0, import_state.createQueryCacheSummaryTool)({
665
+ queryClient,
666
+ allowKeys,
667
+ ...includeDataShape !== void 0 ? { includeDataShape } : {},
668
+ ...includeData !== void 0 ? { includeData } : {},
669
+ ...name ? { name } : {}
670
+ });
671
+ }, [queryClient, allowKeys, includeDataShape, includeData, name]);
672
+ (0, import_react8.useWebMcpTools)([tool], [tool], { source: "diagnostic" });
673
+ }
674
+
675
+ // src/useFormSubmitBlockers.ts
676
+ var import_react9 = require("react");
677
+ var import_react10 = require("@tooluminati/react");
678
+ var import_diagnostics4 = require("@tooluminati/diagnostics");
679
+ function createFormSubmitBlockersProvider(options) {
680
+ return {
681
+ getActionAvailability(actionId) {
682
+ if (actionId !== options.actionId) {
683
+ return void 0;
684
+ }
685
+ const summary = options.getFormSummary();
686
+ const reasons = [
687
+ ...summary.errors.map((e) => `${e.path}: ${e.message}`),
688
+ ...options.getExtraReasons?.() ?? []
689
+ ];
690
+ if (summary.submitting) {
691
+ reasons.push("Form is submitting.");
692
+ }
693
+ return {
694
+ actionId,
695
+ label: options.label,
696
+ available: reasons.length === 0,
697
+ reasons
698
+ };
699
+ },
700
+ listActions() {
701
+ const action = createFormSubmitBlockersProvider(
702
+ options
703
+ ).getActionAvailability(options.actionId);
704
+ return action ? [action] : [];
705
+ }
706
+ };
707
+ }
708
+ function useFormSubmitBlockers(options) {
709
+ const provider = (0, import_react9.useMemo)(
710
+ () => createFormSubmitBlockersProvider(options),
711
+ [options]
712
+ );
713
+ (0, import_react10.useWebMcpTool)((0, import_diagnostics4.createActionAvailabilityTool)(provider), [provider]);
714
+ return provider;
715
+ }
716
+
717
+ // src/declarative-form.tsx
718
+ var import_jsx_runtime4 = require("react/jsx-runtime");
719
+ function WebMcpForm({
720
+ toolName,
721
+ toolDescription,
722
+ toolAutoSubmit,
723
+ children,
724
+ ...props
725
+ }) {
726
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
727
+ "form",
728
+ {
729
+ ...props,
730
+ toolname: toolName,
731
+ tooldescription: toolDescription,
732
+ ...toolAutoSubmit ? { toolautosubmit: "" } : {},
733
+ children
734
+ }
735
+ );
736
+ }
737
+ function WebMcpInput(props) {
738
+ const { toolParamDescription, ...rest } = props;
739
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
740
+ "input",
741
+ {
742
+ ...rest,
743
+ ...toolParamDescription ? { toolparamdescription: toolParamDescription } : {}
744
+ }
745
+ );
746
+ }
747
+ function WebMcpSelect(props) {
748
+ const { toolParamDescription, ...rest } = props;
749
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
750
+ "select",
751
+ {
752
+ ...rest,
753
+ ...toolParamDescription ? { toolparamdescription: toolParamDescription } : {}
754
+ }
755
+ );
756
+ }
757
+ function WebMcpTextarea(props) {
758
+ const { toolParamDescription, ...rest } = props;
759
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
760
+ "textarea",
761
+ {
762
+ ...rest,
763
+ ...toolParamDescription ? { toolparamdescription: toolParamDescription } : {}
764
+ }
765
+ );
766
+ }
767
+ function useAgentInvokedSubmit(handler) {
768
+ return (event) => {
769
+ const submitEvent = event.nativeEvent;
770
+ if (submitEvent.agentInvoked) {
771
+ handler(event);
772
+ }
773
+ };
774
+ }
775
+ function useDeclarativeFormToolEvents(_options = {}) {
776
+ }
777
+
778
+ // src/useTroubleshootingPanel.ts
779
+ var import_react11 = require("react");
780
+ var import_diagnostics5 = require("@tooluminati/diagnostics");
781
+ function useTroubleshootingPanel() {
782
+ const { viewModel } = useWebMcpTroubleshootingContext();
783
+ const [snapshot, setSnapshot] = (0, import_react11.useState)(
784
+ () => viewModel.refresh()
785
+ );
786
+ (0, import_react11.useEffect)(() => {
787
+ const refresh = () => setSnapshot(viewModel.refresh());
788
+ refresh();
789
+ return viewModel.subscribe(refresh);
790
+ }, [viewModel]);
791
+ return {
792
+ snapshot,
793
+ panelState: snapshot.panelState,
794
+ refresh: () => setSnapshot(viewModel.refresh()),
795
+ copyDiagnostics: () => (0, import_diagnostics5.serializeTroubleshootingDiagnostics)(snapshot)
796
+ };
797
+ }
798
+ function useTroubleshootingPanelVisibility() {
799
+ const { visibility, isPanelEnabled } = useWebMcpTroubleshootingContext();
800
+ const [, bump] = (0, import_react11.useState)(0);
801
+ (0, import_react11.useEffect)(() => visibility.subscribe(() => bump((n) => n + 1)), [visibility]);
802
+ return {
803
+ visibility,
804
+ isPanelEnabled,
805
+ visible: visibility.visible,
806
+ collapsed: visibility.collapsed
807
+ };
808
+ }
809
+ // Annotate the CommonJS export names for ESM import in node:
810
+ 0 && (module.exports = {
811
+ WebMcpErrorBoundary,
812
+ WebMcpForm,
813
+ WebMcpInput,
814
+ WebMcpSelect,
815
+ WebMcpTextarea,
816
+ WebMcpTroubleshootingContext,
817
+ WebMcpTroubleshootingPanel,
818
+ WebMcpTroubleshootingProvider,
819
+ createFormSubmitBlockersProvider,
820
+ getPanelVisibilityController,
821
+ hideWebMcpTroubleshootingPanel,
822
+ resetPanelVisibilityController,
823
+ showWebMcpTroubleshootingPanel,
824
+ toggleWebMcpTroubleshootingPanel,
825
+ useAgentInvokedSubmit,
826
+ useDeclarativeFormToolEvents,
827
+ useFormSubmitBlockers,
828
+ useTanStackQueryWebMcpTools,
829
+ useTroubleshootingPanel,
830
+ useTroubleshootingPanelVisibility,
831
+ useWebMcpTroubleshootingContext,
832
+ wirePanelVisibilityController
833
+ });