theokit 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions-virtual-module-E6PU47GV.js +175 -0
- package/dist/actions-virtual-module-E6PU47GV.js.map +1 -0
- package/dist/actions-virtual-module-E7IELVHL.js +174 -0
- package/dist/actions-virtual-module-E7IELVHL.js.map +1 -0
- package/dist/app-typed-client-4L4L4BWD.js +289 -0
- package/dist/app-typed-client-4L4L4BWD.js.map +1 -0
- package/dist/app-typed-client-6PAT6VOL.js +289 -0
- package/dist/app-typed-client-6PAT6VOL.js.map +1 -0
- package/dist/{build-IQQYCA3B.js → build-EWZDEDT3.js} +37 -11
- package/dist/build-EWZDEDT3.js.map +1 -0
- package/dist/build-request-body-preview-EOP2Y4F3.js +52 -0
- package/dist/build-request-body-preview-EOP2Y4F3.js.map +1 -0
- package/dist/build-request-body-preview-II2235E6.js +54 -0
- package/dist/build-request-body-preview-II2235E6.js.map +1 -0
- package/dist/{chunk-GQSTRXXB.js → chunk-2BQYEBCK.js} +77 -68
- package/dist/chunk-2BQYEBCK.js.map +1 -0
- package/dist/{chunk-FRBYJANT.js → chunk-4W447H7M.js} +195 -41
- package/dist/chunk-4W447H7M.js.map +1 -0
- package/dist/chunk-7DHGV77J.js +140 -0
- package/dist/chunk-7DHGV77J.js.map +1 -0
- package/dist/{chunk-WQCPKA2L.js → chunk-C27AZN46.js} +570 -165
- package/dist/chunk-C27AZN46.js.map +1 -0
- package/dist/chunk-ERAZNHHR.js +73 -0
- package/dist/chunk-ERAZNHHR.js.map +1 -0
- package/dist/chunk-F3TG5FJV.js +97 -0
- package/dist/chunk-F3TG5FJV.js.map +1 -0
- package/dist/{chunk-OK2PJOLK.js → chunk-KJVEJILQ.js} +7 -3
- package/dist/chunk-KJVEJILQ.js.map +1 -0
- package/dist/{chunk-JBC7PFV4.js → chunk-M23FP2AS.js} +2 -2
- package/dist/chunk-M23FP2AS.js.map +1 -0
- package/dist/{chunk-S3JBIFKS.js → chunk-MG7H3LAW.js} +2 -2
- package/dist/chunk-MOT42NAH.js +165 -0
- package/dist/chunk-MOT42NAH.js.map +1 -0
- package/dist/{chunk-OEB3OIYP.js → chunk-OJHO2X7C.js} +497 -168
- package/dist/chunk-OJHO2X7C.js.map +1 -0
- package/dist/chunk-QLGES2HC.js +189 -0
- package/dist/chunk-QLGES2HC.js.map +1 -0
- package/dist/{chunk-JZ5WEG3S.js → chunk-SEVYARIU.js} +9 -5
- package/dist/chunk-SEVYARIU.js.map +1 -0
- package/dist/{chunk-ZK5JCE5J.js → chunk-TFECHXR5.js} +201 -43
- package/dist/chunk-TFECHXR5.js.map +1 -0
- package/dist/chunk-WSJKACWB.js +17 -0
- package/dist/chunk-WSJKACWB.js.map +1 -0
- package/dist/{chunk-3Q36SEDK.js → chunk-ZBWROIIO.js} +43 -2
- package/dist/{chunk-3Q36SEDK.js.map → chunk-ZBWROIIO.js.map} +1 -1
- package/dist/chunk-ZOXNJV2O.js +358 -0
- package/dist/chunk-ZOXNJV2O.js.map +1 -0
- package/dist/cli/index.js +22 -7
- package/dist/cli/index.js.map +1 -1
- package/dist/client/index.d.ts +31 -1
- package/dist/client/index.js +100 -0
- package/dist/client/index.js.map +1 -1
- package/dist/{dev-VN6WS3CM.js → dev-74KPI5C5.js} +15 -7
- package/dist/dev-74KPI5C5.js.map +1 -0
- package/dist/dev-emit-3CHM73TV.js +390 -0
- package/dist/dev-emit-3CHM73TV.js.map +1 -0
- package/dist/dev-emit-I3CKOHML.js +44 -0
- package/dist/dev-emit-I3CKOHML.js.map +1 -0
- package/dist/devtools/entry.js +545 -181
- package/dist/devtools/entry.js.map +1 -1
- package/dist/{dispatcher-IK3FVMX5.js → dispatcher-AQJGI3HU.js} +2 -2
- package/dist/dispatcher-E6QV32BO.js +83 -0
- package/dist/dispatcher-E6QV32BO.js.map +1 -0
- package/dist/{dist-Q5VBFWVL.js → dist-R2Q7GVDW.js} +10357 -12068
- package/dist/dist-R2Q7GVDW.js.map +1 -0
- package/dist/{generate-SIO4JSKJ.js → generate-DT4IIAHF.js} +88 -22
- package/dist/generate-DT4IIAHF.js.map +1 -0
- package/dist/index.d.ts +108 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/{info-B3UOXFUF.js → info-VM7EK4JC.js} +3 -3
- package/dist/openapi-CBASKC7W.js +84 -0
- package/dist/openapi-CBASKC7W.js.map +1 -0
- package/dist/{registry-BB3UYAOG.js → registry-QGSNLJKJ.js} +2 -2
- package/dist/{routes-CAGFZKUK.js → routes-7O4NUDYS.js} +9 -7
- package/dist/{routes-CAGFZKUK.js.map → routes-7O4NUDYS.js.map} +1 -1
- package/dist/{schema-Cxq2qqwh.d.ts → schema-CjVly9c_.d.ts} +43 -1
- package/dist/{schema-MVB2FVK6.js → schema-JAKF23GR.js} +2 -2
- package/dist/server/cost/index.js +1 -1
- package/dist/server/index.d.ts +219 -47
- package/dist/server/index.js +35 -116
- package/dist/server/index.js.map +1 -1
- package/dist/{start-ZGWW5MOL.js → start-5JTFWF4T.js} +20 -14
- package/dist/start-5JTFWF4T.js.map +1 -0
- package/dist/{static-BH6JQNM2.js → static-6PZZBY7G.js} +4 -4
- package/dist/{upgrade-readiness-OHL36FQL.js → upgrade-readiness-Q46KTG2J.js} +6 -1
- package/dist/upgrade-readiness-Q46KTG2J.js.map +1 -0
- package/dist/vite-plugin/index.d.ts +25 -1
- package/dist/vite-plugin/index.js +5 -2
- package/dist/{vite-plugin-WA3G45YY.js → vite-plugin-3EQP2JYM.js} +7 -6
- package/package.json +4 -2
- package/dist/build-IQQYCA3B.js.map +0 -1
- package/dist/chunk-FRBYJANT.js.map +0 -1
- package/dist/chunk-GQSTRXXB.js.map +0 -1
- package/dist/chunk-JBC7PFV4.js.map +0 -1
- package/dist/chunk-JZ5WEG3S.js.map +0 -1
- package/dist/chunk-OEB3OIYP.js.map +0 -1
- package/dist/chunk-OK2PJOLK.js.map +0 -1
- package/dist/chunk-WQCPKA2L.js.map +0 -1
- package/dist/chunk-ZK5JCE5J.js.map +0 -1
- package/dist/dev-VN6WS3CM.js.map +0 -1
- package/dist/dist-Q5VBFWVL.js.map +0 -1
- package/dist/generate-SIO4JSKJ.js.map +0 -1
- package/dist/start-ZGWW5MOL.js.map +0 -1
- package/dist/upgrade-readiness-OHL36FQL.js.map +0 -1
- /package/dist/{chunk-S3JBIFKS.js.map → chunk-MG7H3LAW.js.map} +0 -0
- /package/dist/{dispatcher-IK3FVMX5.js.map → dispatcher-AQJGI3HU.js.map} +0 -0
- /package/dist/{info-B3UOXFUF.js.map → info-VM7EK4JC.js.map} +0 -0
- /package/dist/{registry-BB3UYAOG.js.map → registry-QGSNLJKJ.js.map} +0 -0
- /package/dist/{schema-MVB2FVK6.js.map → schema-JAKF23GR.js.map} +0 -0
- /package/dist/{static-BH6JQNM2.js.map → static-6PZZBY7G.js.map} +0 -0
- /package/dist/{vite-plugin-WA3G45YY.js.map → vite-plugin-3EQP2JYM.js.map} +0 -0
package/dist/devtools/entry.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
STORAGE_VERSION,
|
|
9
9
|
dispatcher,
|
|
10
10
|
initialState
|
|
11
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-KJVEJILQ.js";
|
|
12
12
|
import "../chunk-DGUM43GV.js";
|
|
13
13
|
|
|
14
14
|
// src/devtools/entry.tsx
|
|
@@ -444,12 +444,278 @@ function Indicator() {
|
|
|
444
444
|
);
|
|
445
445
|
}
|
|
446
446
|
|
|
447
|
-
// src/devtools/components/Tabs/
|
|
447
|
+
// src/devtools/components/Tabs/ActionsTab.tsx
|
|
448
|
+
import { useState } from "react";
|
|
449
|
+
|
|
450
|
+
// src/devtools/actions-row-state.ts
|
|
451
|
+
function toggleExpandedIds(prev, id) {
|
|
452
|
+
const next = new Set(prev);
|
|
453
|
+
if (next.has(id)) {
|
|
454
|
+
next.delete(id);
|
|
455
|
+
} else {
|
|
456
|
+
next.add(id);
|
|
457
|
+
}
|
|
458
|
+
return next;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
// src/devtools/pii-mask.ts
|
|
462
|
+
var SENSITIVE_KEY_PATTERN = /(password|token|secret|api_?key|apikey|credit_?card|ssn|cpf|cnpj)/i;
|
|
463
|
+
function isSensitiveKey(key) {
|
|
464
|
+
return SENSITIVE_KEY_PATTERN.test(key);
|
|
465
|
+
}
|
|
466
|
+
function maskPiiFields(value) {
|
|
467
|
+
if (value === null || value === void 0) return value;
|
|
468
|
+
if (typeof value !== "object") return value;
|
|
469
|
+
if (Array.isArray(value)) {
|
|
470
|
+
return value.map((item) => maskPiiFields(item));
|
|
471
|
+
}
|
|
472
|
+
const out = {};
|
|
473
|
+
for (const [key, val] of Object.entries(value)) {
|
|
474
|
+
if (isSensitiveKey(key)) {
|
|
475
|
+
out[key] = "***";
|
|
476
|
+
} else {
|
|
477
|
+
out[key] = maskPiiFields(val);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
return out;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// src/devtools/components/Tabs/ActionsTab.tsx
|
|
448
484
|
import { jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
449
485
|
function formatTime(ts) {
|
|
450
486
|
const d = new Date(ts);
|
|
451
487
|
return d.toLocaleTimeString(void 0, { hour: "2-digit", minute: "2-digit", second: "2-digit" });
|
|
452
488
|
}
|
|
489
|
+
function formatPayload(value, reveal) {
|
|
490
|
+
const display = reveal ? value : maskPiiFields(value);
|
|
491
|
+
try {
|
|
492
|
+
return JSON.stringify(display, null, 2);
|
|
493
|
+
} catch {
|
|
494
|
+
return "<unserializable>";
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
function buildActionsStyles(styles) {
|
|
498
|
+
return {
|
|
499
|
+
header: styles.css`
|
|
500
|
+
display: flex;
|
|
501
|
+
align-items: center;
|
|
502
|
+
justify-content: space-between;
|
|
503
|
+
padding: ${tokens.spacing.xs} ${tokens.spacing.sm};
|
|
504
|
+
color: ${tokens.colors.textMuted};
|
|
505
|
+
font-size: ${tokens.font.sizeXs};
|
|
506
|
+
border-bottom: 1px solid ${tokens.colors.borderSubtle};
|
|
507
|
+
`,
|
|
508
|
+
clearBtn: styles.css`
|
|
509
|
+
appearance: none;
|
|
510
|
+
background: transparent;
|
|
511
|
+
color: ${tokens.colors.textMuted};
|
|
512
|
+
border: 1px solid ${tokens.colors.borderSubtle};
|
|
513
|
+
padding: 2px 6px;
|
|
514
|
+
border-radius: ${tokens.radius.sm};
|
|
515
|
+
cursor: pointer;
|
|
516
|
+
font-size: ${tokens.font.sizeXs};
|
|
517
|
+
&:hover { color: ${tokens.colors.text}; }
|
|
518
|
+
`,
|
|
519
|
+
rowContainer: styles.css`
|
|
520
|
+
border-bottom: 1px solid ${tokens.colors.borderSubtle};
|
|
521
|
+
font-size: ${tokens.font.sizeXs};
|
|
522
|
+
`,
|
|
523
|
+
rowSummary: styles.css`
|
|
524
|
+
display: grid;
|
|
525
|
+
grid-template-columns: 24px 80px 1fr 80px 80px;
|
|
526
|
+
gap: ${tokens.spacing.sm};
|
|
527
|
+
align-items: center;
|
|
528
|
+
width: 100%;
|
|
529
|
+
padding: ${tokens.spacing.xs} ${tokens.spacing.sm};
|
|
530
|
+
background: transparent;
|
|
531
|
+
border: none;
|
|
532
|
+
color: ${tokens.colors.text};
|
|
533
|
+
text-align: left;
|
|
534
|
+
cursor: pointer;
|
|
535
|
+
font-family: ${tokens.font.family};
|
|
536
|
+
font-size: ${tokens.font.sizeXs};
|
|
537
|
+
&:hover { background: ${tokens.colors.bgPanelHover}; }
|
|
538
|
+
&[aria-expanded='true'] { background: ${tokens.colors.bgPanelHover}; }
|
|
539
|
+
.chev { color: ${tokens.colors.textMuted}; font-family: ${tokens.font.mono}; }
|
|
540
|
+
.name { font-family: ${tokens.font.mono}; }
|
|
541
|
+
.time { color: ${tokens.colors.textMuted}; font-family: ${tokens.font.mono}; }
|
|
542
|
+
.status-success { color: ${tokens.colors.accent}; }
|
|
543
|
+
.status-error { color: #c92a2a; }
|
|
544
|
+
.duration { color: ${tokens.colors.textMuted}; text-align: right; }
|
|
545
|
+
`,
|
|
546
|
+
detail: styles.css`
|
|
547
|
+
padding: ${tokens.spacing.sm} ${tokens.spacing.md};
|
|
548
|
+
background: ${tokens.colors.bgPanelHover};
|
|
549
|
+
border-top: 1px dashed ${tokens.colors.borderSubtle};
|
|
550
|
+
font-size: ${tokens.font.sizeXs};
|
|
551
|
+
pre {
|
|
552
|
+
margin: 0;
|
|
553
|
+
padding: ${tokens.spacing.xs};
|
|
554
|
+
background: ${tokens.colors.borderSubtle};
|
|
555
|
+
border-radius: ${tokens.radius.sm};
|
|
556
|
+
overflow: auto;
|
|
557
|
+
max-height: 200px;
|
|
558
|
+
font-family: ${tokens.font.mono};
|
|
559
|
+
}
|
|
560
|
+
.reveal-btn {
|
|
561
|
+
appearance: none;
|
|
562
|
+
background: transparent;
|
|
563
|
+
color: ${tokens.colors.textMuted};
|
|
564
|
+
border: 1px solid ${tokens.colors.borderSubtle};
|
|
565
|
+
padding: 2px 8px;
|
|
566
|
+
margin-bottom: ${tokens.spacing.xs};
|
|
567
|
+
border-radius: ${tokens.radius.sm};
|
|
568
|
+
cursor: pointer;
|
|
569
|
+
font-size: ${tokens.font.sizeXs};
|
|
570
|
+
}
|
|
571
|
+
.reveal-btn:hover { color: ${tokens.colors.text}; }
|
|
572
|
+
.section { margin-top: ${tokens.spacing.sm}; }
|
|
573
|
+
.field-errors { margin-top: ${tokens.spacing.xs}; color: #c92a2a; }
|
|
574
|
+
.field-errors li { margin-left: ${tokens.spacing.md}; }
|
|
575
|
+
`
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
function ActionsEmptyState() {
|
|
579
|
+
return /* @__PURE__ */ jsxs("div", { style: { color: tokens.colors.textMuted, padding: tokens.spacing.md }, children: [
|
|
580
|
+
"No action calls yet. Trigger a server action (via ",
|
|
581
|
+
/* @__PURE__ */ jsx3("code", { children: "useAction" }),
|
|
582
|
+
" or direct",
|
|
583
|
+
" ",
|
|
584
|
+
/* @__PURE__ */ jsx3("code", { children: "POST /_actions/<name>" }),
|
|
585
|
+
") to see it here. Production builds tree-shake this telemetry path."
|
|
586
|
+
] });
|
|
587
|
+
}
|
|
588
|
+
function ActionsTab() {
|
|
589
|
+
const { state, dispatch, styles } = useDevtoolsContext();
|
|
590
|
+
const [revealedIds, setRevealedIds] = useState(() => /* @__PURE__ */ new Set());
|
|
591
|
+
const [expandedIds, setExpandedIds] = useState(() => /* @__PURE__ */ new Set());
|
|
592
|
+
if (state.actionCalls.length === 0) return /* @__PURE__ */ jsx3(ActionsEmptyState, {});
|
|
593
|
+
const cls = buildActionsStyles(styles);
|
|
594
|
+
const toggleReveal = (id) => {
|
|
595
|
+
setRevealedIds((prev) => toggleExpandedIds(prev, id));
|
|
596
|
+
};
|
|
597
|
+
const toggleExpand = (id) => {
|
|
598
|
+
setExpandedIds((prev) => toggleExpandedIds(prev, id));
|
|
599
|
+
};
|
|
600
|
+
return /* @__PURE__ */ jsxs("div", { "data-testid": "devtools-actions-tab", children: [
|
|
601
|
+
/* @__PURE__ */ jsx3(
|
|
602
|
+
ActionsHeader,
|
|
603
|
+
{
|
|
604
|
+
className: cls.header,
|
|
605
|
+
clearBtnClass: cls.clearBtn,
|
|
606
|
+
count: state.actionCalls.length,
|
|
607
|
+
onClear: () => {
|
|
608
|
+
dispatch({ type: "RESET_ACTION_CALLS" });
|
|
609
|
+
setRevealedIds(/* @__PURE__ */ new Set());
|
|
610
|
+
setExpandedIds(/* @__PURE__ */ new Set());
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
),
|
|
614
|
+
/* @__PURE__ */ jsx3("div", { children: state.actionCalls.map((r) => /* @__PURE__ */ jsx3(
|
|
615
|
+
ActionRow,
|
|
616
|
+
{
|
|
617
|
+
record: r,
|
|
618
|
+
containerClass: cls.rowContainer,
|
|
619
|
+
summaryClass: cls.rowSummary,
|
|
620
|
+
detailClass: cls.detail,
|
|
621
|
+
expanded: expandedIds.has(r.id),
|
|
622
|
+
revealed: revealedIds.has(r.id),
|
|
623
|
+
onToggleExpand: () => {
|
|
624
|
+
toggleExpand(r.id);
|
|
625
|
+
},
|
|
626
|
+
onToggleReveal: () => {
|
|
627
|
+
toggleReveal(r.id);
|
|
628
|
+
}
|
|
629
|
+
},
|
|
630
|
+
r.id
|
|
631
|
+
)) })
|
|
632
|
+
] });
|
|
633
|
+
}
|
|
634
|
+
function ActionsHeader({
|
|
635
|
+
className,
|
|
636
|
+
clearBtnClass,
|
|
637
|
+
count,
|
|
638
|
+
onClear
|
|
639
|
+
}) {
|
|
640
|
+
return /* @__PURE__ */ jsxs("div", { className, children: [
|
|
641
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
642
|
+
count,
|
|
643
|
+
" call",
|
|
644
|
+
count === 1 ? "" : "s"
|
|
645
|
+
] }),
|
|
646
|
+
/* @__PURE__ */ jsx3("button", { type: "button", className: clearBtnClass, onClick: onClear, children: "Clear" })
|
|
647
|
+
] });
|
|
648
|
+
}
|
|
649
|
+
function ActionRow({
|
|
650
|
+
record,
|
|
651
|
+
containerClass,
|
|
652
|
+
summaryClass,
|
|
653
|
+
detailClass,
|
|
654
|
+
expanded,
|
|
655
|
+
revealed,
|
|
656
|
+
onToggleExpand,
|
|
657
|
+
onToggleReveal
|
|
658
|
+
}) {
|
|
659
|
+
const statusClass = record.status === "success" ? "status-success" : "status-error";
|
|
660
|
+
return /* @__PURE__ */ jsxs("div", { className: containerClass, "data-testid": "devtools-action-row", children: [
|
|
661
|
+
/* @__PURE__ */ jsxs(
|
|
662
|
+
"button",
|
|
663
|
+
{
|
|
664
|
+
type: "button",
|
|
665
|
+
className: summaryClass,
|
|
666
|
+
onClick: onToggleExpand,
|
|
667
|
+
"aria-expanded": expanded,
|
|
668
|
+
title: `${record.name} \u2014 click to ${expanded ? "collapse" : "expand"} details`,
|
|
669
|
+
children: [
|
|
670
|
+
/* @__PURE__ */ jsx3("span", { className: "chev", children: expanded ? "\u25BC" : "\u25B6" }),
|
|
671
|
+
/* @__PURE__ */ jsx3("span", { className: "time", children: formatTime(record.timestamp) }),
|
|
672
|
+
/* @__PURE__ */ jsx3("span", { className: "name", children: record.name }),
|
|
673
|
+
/* @__PURE__ */ jsx3("span", { className: statusClass, children: record.status }),
|
|
674
|
+
/* @__PURE__ */ jsxs("span", { className: "duration", children: [
|
|
675
|
+
record.durationMs,
|
|
676
|
+
"ms"
|
|
677
|
+
] })
|
|
678
|
+
]
|
|
679
|
+
}
|
|
680
|
+
),
|
|
681
|
+
expanded && /* @__PURE__ */ jsxs("div", { className: detailClass, children: [
|
|
682
|
+
/* @__PURE__ */ jsx3("button", { type: "button", className: "reveal-btn", onClick: onToggleReveal, children: revealed ? "Hide values" : "Reveal values" }),
|
|
683
|
+
/* @__PURE__ */ jsxs("div", { className: "section", children: [
|
|
684
|
+
/* @__PURE__ */ jsx3("strong", { children: "Input" }),
|
|
685
|
+
/* @__PURE__ */ jsx3("pre", { children: formatPayload(record.input, revealed) })
|
|
686
|
+
] }),
|
|
687
|
+
record.status === "success" && record.output !== void 0 && /* @__PURE__ */ jsxs("div", { className: "section", children: [
|
|
688
|
+
/* @__PURE__ */ jsx3("strong", { children: "Output" }),
|
|
689
|
+
/* @__PURE__ */ jsx3("pre", { children: formatPayload(record.output, revealed) })
|
|
690
|
+
] }),
|
|
691
|
+
record.status === "error" && record.error && /* @__PURE__ */ jsx3(ActionDetailError, { error: record.error })
|
|
692
|
+
] })
|
|
693
|
+
] });
|
|
694
|
+
}
|
|
695
|
+
function ActionDetailError({ error }) {
|
|
696
|
+
return /* @__PURE__ */ jsxs("div", { className: "section", children: [
|
|
697
|
+
/* @__PURE__ */ jsxs("strong", { children: [
|
|
698
|
+
"Error: ",
|
|
699
|
+
error.code
|
|
700
|
+
] }),
|
|
701
|
+
/* @__PURE__ */ jsx3("p", { children: error.message }),
|
|
702
|
+
error.fields && Object.keys(error.fields).length > 0 && /* @__PURE__ */ jsx3("ul", { className: "field-errors", children: Object.entries(error.fields).map(([field, msgs]) => /* @__PURE__ */ jsxs("li", { children: [
|
|
703
|
+
/* @__PURE__ */ jsxs("strong", { children: [
|
|
704
|
+
field || "(root)",
|
|
705
|
+
":"
|
|
706
|
+
] }),
|
|
707
|
+
" ",
|
|
708
|
+
msgs.join("; ")
|
|
709
|
+
] }, field)) })
|
|
710
|
+
] });
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
// src/devtools/components/Tabs/AgentsTab.tsx
|
|
714
|
+
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
715
|
+
function formatTime2(ts) {
|
|
716
|
+
const d = new Date(ts);
|
|
717
|
+
return d.toLocaleTimeString(void 0, { hour: "2-digit", minute: "2-digit", second: "2-digit" });
|
|
718
|
+
}
|
|
453
719
|
function formatCost(usd) {
|
|
454
720
|
if (usd === 0) return "$0.0000";
|
|
455
721
|
if (usd < 1e-4) return `<$0.0001`;
|
|
@@ -458,9 +724,9 @@ function formatCost(usd) {
|
|
|
458
724
|
function AgentsTab() {
|
|
459
725
|
const { state, dispatch, styles } = useDevtoolsContext();
|
|
460
726
|
if (state.agentRuns.length === 0) {
|
|
461
|
-
return /* @__PURE__ */
|
|
727
|
+
return /* @__PURE__ */ jsxs2("div", { style: { color: tokens.colors.textMuted, padding: tokens.spacing.md }, children: [
|
|
462
728
|
"No agent runs yet. Trigger a request to an endpoint using ",
|
|
463
|
-
/* @__PURE__ */
|
|
729
|
+
/* @__PURE__ */ jsx4("code", { children: "trackAgentRun" }),
|
|
464
730
|
" to see it here. (Wired in the saas template; opt-in elsewhere.)"
|
|
465
731
|
] });
|
|
466
732
|
}
|
|
@@ -504,9 +770,9 @@ function AgentsTab() {
|
|
|
504
770
|
tr.status-error td { color: #c92a2a; }
|
|
505
771
|
tr.status-aborted td { color: ${tokens.colors.textMuted}; }
|
|
506
772
|
`;
|
|
507
|
-
return /* @__PURE__ */
|
|
508
|
-
/* @__PURE__ */
|
|
509
|
-
/* @__PURE__ */
|
|
773
|
+
return /* @__PURE__ */ jsxs2("div", { "data-testid": "devtools-agents-tab", children: [
|
|
774
|
+
/* @__PURE__ */ jsxs2("div", { className: headerClass, children: [
|
|
775
|
+
/* @__PURE__ */ jsxs2("span", { children: [
|
|
510
776
|
state.agentRuns.length,
|
|
511
777
|
" run",
|
|
512
778
|
state.agentRuns.length === 1 ? "" : "s",
|
|
@@ -519,7 +785,7 @@ function AgentsTab() {
|
|
|
519
785
|
formatCost(totalCost),
|
|
520
786
|
" total"
|
|
521
787
|
] }),
|
|
522
|
-
/* @__PURE__ */
|
|
788
|
+
/* @__PURE__ */ jsx4(
|
|
523
789
|
"button",
|
|
524
790
|
{
|
|
525
791
|
type: "button",
|
|
@@ -531,34 +797,95 @@ function AgentsTab() {
|
|
|
531
797
|
}
|
|
532
798
|
)
|
|
533
799
|
] }),
|
|
534
|
-
/* @__PURE__ */
|
|
535
|
-
/* @__PURE__ */
|
|
536
|
-
/* @__PURE__ */
|
|
537
|
-
/* @__PURE__ */
|
|
538
|
-
/* @__PURE__ */
|
|
539
|
-
/* @__PURE__ */
|
|
540
|
-
/* @__PURE__ */
|
|
541
|
-
/* @__PURE__ */
|
|
800
|
+
/* @__PURE__ */ jsxs2("table", { className: tableClass, children: [
|
|
801
|
+
/* @__PURE__ */ jsx4("thead", { children: /* @__PURE__ */ jsxs2("tr", { children: [
|
|
802
|
+
/* @__PURE__ */ jsx4("th", { children: "Time" }),
|
|
803
|
+
/* @__PURE__ */ jsx4("th", { children: "User" }),
|
|
804
|
+
/* @__PURE__ */ jsx4("th", { children: "Model" }),
|
|
805
|
+
/* @__PURE__ */ jsx4("th", { children: "Tokens (in/out)" }),
|
|
806
|
+
/* @__PURE__ */ jsx4("th", { children: "Cost" }),
|
|
807
|
+
/* @__PURE__ */ jsx4("th", { children: "Status" })
|
|
542
808
|
] }) }),
|
|
543
|
-
/* @__PURE__ */
|
|
544
|
-
/* @__PURE__ */
|
|
545
|
-
/* @__PURE__ */
|
|
546
|
-
/* @__PURE__ */
|
|
547
|
-
/* @__PURE__ */
|
|
809
|
+
/* @__PURE__ */ jsx4("tbody", { children: state.agentRuns.map((run) => /* @__PURE__ */ jsxs2("tr", { className: `status-${run.status}`, children: [
|
|
810
|
+
/* @__PURE__ */ jsx4("td", { children: formatTime2(run.timestamp) }),
|
|
811
|
+
/* @__PURE__ */ jsx4("td", { children: run.userId }),
|
|
812
|
+
/* @__PURE__ */ jsx4("td", { children: run.model }),
|
|
813
|
+
/* @__PURE__ */ jsxs2("td", { children: [
|
|
548
814
|
run.tokensInput,
|
|
549
815
|
"/",
|
|
550
816
|
run.tokensOutput
|
|
551
817
|
] }),
|
|
552
|
-
/* @__PURE__ */
|
|
553
|
-
/* @__PURE__ */
|
|
818
|
+
/* @__PURE__ */ jsx4("td", { children: formatCost(run.costUsd) }),
|
|
819
|
+
/* @__PURE__ */ jsx4("td", { children: run.status })
|
|
554
820
|
] }, run.id)) })
|
|
555
821
|
] })
|
|
556
822
|
] });
|
|
557
823
|
}
|
|
558
824
|
|
|
559
825
|
// src/devtools/components/Tabs/CsrfReadinessTab.tsx
|
|
560
|
-
import { useEffect as useEffect2, useState, useCallback as useCallback2 } from "react";
|
|
561
|
-
|
|
826
|
+
import { useEffect as useEffect2, useState as useState2, useCallback as useCallback2 } from "react";
|
|
827
|
+
|
|
828
|
+
// src/devtools/csrf-readiness-classify.ts
|
|
829
|
+
var NETWORK_ERROR_PATTERN = /failed to fetch|networkerror|network request failed/i;
|
|
830
|
+
function classifyCsrfReadinessError(input) {
|
|
831
|
+
if (input.kind === "http") {
|
|
832
|
+
return classifyHttpStatus(input.status);
|
|
833
|
+
}
|
|
834
|
+
return classifyThrown(input.error);
|
|
835
|
+
}
|
|
836
|
+
function classifyHttpStatus(status) {
|
|
837
|
+
if (status === 404) {
|
|
838
|
+
return {
|
|
839
|
+
kind: "store-not-wired",
|
|
840
|
+
summary: `Endpoint returned 404 \u2014 /__theo/csrf-readiness not registered.`,
|
|
841
|
+
hint: "Wire `csrfReadinessStore` in the api-middleware options to enable this tab."
|
|
842
|
+
};
|
|
843
|
+
}
|
|
844
|
+
if (status === 401 || status === 403) {
|
|
845
|
+
return {
|
|
846
|
+
kind: "unauthorized",
|
|
847
|
+
summary: `Endpoint returned ${String(status)} \u2014 the readiness route is auth-gated.`,
|
|
848
|
+
hint: "Authenticate (e.g. via session) before opening this tab, or move the route outside of requireAuth."
|
|
849
|
+
};
|
|
850
|
+
}
|
|
851
|
+
if (status >= 500 && status < 600) {
|
|
852
|
+
return {
|
|
853
|
+
kind: "server-crash",
|
|
854
|
+
summary: `Endpoint returned ${String(status)} \u2014 the readiness handler threw.`,
|
|
855
|
+
hint: "Check dev server logs (terminal running `theokit dev`) for the underlying stack trace."
|
|
856
|
+
};
|
|
857
|
+
}
|
|
858
|
+
return {
|
|
859
|
+
kind: "unexpected-status",
|
|
860
|
+
summary: `Endpoint returned unexpected status ${String(status)}.`,
|
|
861
|
+
hint: "This is not a status the readiness route normally emits. Inspect the response body in Network tab."
|
|
862
|
+
};
|
|
863
|
+
}
|
|
864
|
+
function classifyThrown(error) {
|
|
865
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
866
|
+
return {
|
|
867
|
+
kind: "aborted",
|
|
868
|
+
summary: "Request aborted.",
|
|
869
|
+
hint: ""
|
|
870
|
+
};
|
|
871
|
+
}
|
|
872
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
873
|
+
if (error instanceof TypeError && NETWORK_ERROR_PATTERN.test(message)) {
|
|
874
|
+
return {
|
|
875
|
+
kind: "server-unreachable",
|
|
876
|
+
summary: "Dev server unreachable \u2014 request failed before any HTTP response.",
|
|
877
|
+
hint: "Restart the dev server (`theokit dev`) and verify the port matches the browser URL."
|
|
878
|
+
};
|
|
879
|
+
}
|
|
880
|
+
return {
|
|
881
|
+
kind: "unknown-error",
|
|
882
|
+
summary: message.length > 0 ? message : "Unknown error",
|
|
883
|
+
hint: "Open the browser DevTools Network panel to inspect the failed request."
|
|
884
|
+
};
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
// src/devtools/components/Tabs/CsrfReadinessTab.tsx
|
|
888
|
+
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
562
889
|
function buildTabStyles(styles) {
|
|
563
890
|
return {
|
|
564
891
|
container: styles.css`
|
|
@@ -600,13 +927,13 @@ function ReadinessRow({
|
|
|
600
927
|
rowClass,
|
|
601
928
|
route
|
|
602
929
|
}) {
|
|
603
|
-
return /* @__PURE__ */
|
|
604
|
-
/* @__PURE__ */
|
|
605
|
-
/* @__PURE__ */
|
|
930
|
+
return /* @__PURE__ */ jsxs3("div", { className: rowClass, children: [
|
|
931
|
+
/* @__PURE__ */ jsx5("span", { style: { color: tokens.colors.accent }, children: route.method }),
|
|
932
|
+
/* @__PURE__ */ jsxs3("span", { children: [
|
|
606
933
|
route.path,
|
|
607
|
-
/* @__PURE__ */
|
|
934
|
+
/* @__PURE__ */ jsx5("span", { style: { color: tokens.colors.textMuted, marginLeft: tokens.spacing.sm }, children: route.reason })
|
|
608
935
|
] }),
|
|
609
|
-
/* @__PURE__ */
|
|
936
|
+
/* @__PURE__ */ jsxs3("span", { style: { color: tokens.colors.textMuted }, children: [
|
|
610
937
|
"\xD7",
|
|
611
938
|
String(route.count)
|
|
612
939
|
] })
|
|
@@ -615,21 +942,23 @@ function ReadinessRow({
|
|
|
615
942
|
function CsrfReadinessTab() {
|
|
616
943
|
const { styles } = useDevtoolsContext();
|
|
617
944
|
const cls = buildTabStyles(styles);
|
|
618
|
-
const [data, setData] =
|
|
619
|
-
const [error, setError] =
|
|
620
|
-
const [busy, setBusy] =
|
|
945
|
+
const [data, setData] = useState2(null);
|
|
946
|
+
const [error, setError] = useState2(null);
|
|
947
|
+
const [busy, setBusy] = useState2(false);
|
|
621
948
|
const fetchData = useCallback2(async () => {
|
|
622
949
|
try {
|
|
623
950
|
const res = await fetch("/__theo/csrf-readiness");
|
|
624
951
|
if (!res.ok) {
|
|
625
|
-
setError(
|
|
952
|
+
setError(classifyCsrfReadinessError({ kind: "http", status: res.status }));
|
|
626
953
|
return;
|
|
627
954
|
}
|
|
628
955
|
const json = await res.json();
|
|
629
956
|
setData(json);
|
|
630
957
|
setError(null);
|
|
631
958
|
} catch (e) {
|
|
632
|
-
|
|
959
|
+
const classified = classifyCsrfReadinessError({ kind: "thrown", error: e });
|
|
960
|
+
if (classified.kind === "aborted") return;
|
|
961
|
+
setError(classified);
|
|
633
962
|
}
|
|
634
963
|
}, []);
|
|
635
964
|
useEffect2(() => {
|
|
@@ -652,24 +981,28 @@ function CsrfReadinessTab() {
|
|
|
652
981
|
}
|
|
653
982
|
}, [fetchData]);
|
|
654
983
|
if (error) {
|
|
655
|
-
return /* @__PURE__ */
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
"
|
|
661
|
-
|
|
662
|
-
|
|
984
|
+
return /* @__PURE__ */ jsxs3(
|
|
985
|
+
"div",
|
|
986
|
+
{
|
|
987
|
+
className: cls.container,
|
|
988
|
+
"data-testid": "devtools-csrf-readiness-error",
|
|
989
|
+
"data-error-kind": error.kind,
|
|
990
|
+
children: [
|
|
991
|
+
/* @__PURE__ */ jsx5("div", { style: { color: tokens.colors.error.csrf }, children: error.summary }),
|
|
992
|
+
error.hint.length > 0 && /* @__PURE__ */ jsx5("p", { style: { color: tokens.colors.textMuted, marginTop: tokens.spacing.sm }, children: error.hint })
|
|
993
|
+
]
|
|
994
|
+
}
|
|
995
|
+
);
|
|
663
996
|
}
|
|
664
997
|
if (data === null) {
|
|
665
|
-
return /* @__PURE__ */
|
|
998
|
+
return /* @__PURE__ */ jsx5("div", { className: cls.container, "data-testid": "devtools-csrf-readiness-loading", children: "Loading\u2026" });
|
|
666
999
|
}
|
|
667
1000
|
const isEmpty = data.totalEvents === 0;
|
|
668
1001
|
const testid = isEmpty ? "devtools-csrf-readiness-empty" : "devtools-csrf-readiness";
|
|
669
|
-
return /* @__PURE__ */
|
|
670
|
-
/* @__PURE__ */
|
|
671
|
-
/* @__PURE__ */
|
|
672
|
-
/* @__PURE__ */
|
|
1002
|
+
return /* @__PURE__ */ jsxs3("div", { className: cls.container, "data-testid": testid, children: [
|
|
1003
|
+
/* @__PURE__ */ jsxs3("div", { className: cls.headerRow, children: [
|
|
1004
|
+
/* @__PURE__ */ jsx5("strong", { children: isEmpty ? "CSRF Readiness" : `CSRF Readiness \u2014 ${String(data.totalEvents)} event(s) across ${String(data.routes.length)} route(s)` }),
|
|
1005
|
+
/* @__PURE__ */ jsx5(
|
|
673
1006
|
"button",
|
|
674
1007
|
{
|
|
675
1008
|
type: "button",
|
|
@@ -682,13 +1015,13 @@ function CsrfReadinessTab() {
|
|
|
682
1015
|
}
|
|
683
1016
|
)
|
|
684
1017
|
] }),
|
|
685
|
-
isEmpty ? /* @__PURE__ */
|
|
1018
|
+
isEmpty ? /* @__PURE__ */ jsx5("div", { style: { color: tokens.colors.textMuted }, children: "No csrf.warn events recorded. Endpoints are ready for 0.3.0 strict CSRF." }) : data.routes.map((r) => /* @__PURE__ */ jsx5(ReadinessRow, { rowClass: cls.row, route: r }, `${r.method} ${r.path} ${r.reason}`))
|
|
686
1019
|
] });
|
|
687
1020
|
}
|
|
688
1021
|
|
|
689
1022
|
// src/devtools/components/ErrorRow.tsx
|
|
690
|
-
import { useState as
|
|
691
|
-
import { jsx as
|
|
1023
|
+
import { useState as useState3 } from "react";
|
|
1024
|
+
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
692
1025
|
var STACK_DISPLAY_LIMIT = 4096;
|
|
693
1026
|
function truncateStackForDisplay(stack, limit = STACK_DISPLAY_LIMIT) {
|
|
694
1027
|
if (!stack) return null;
|
|
@@ -719,7 +1052,7 @@ function typeIcon(type) {
|
|
|
719
1052
|
}
|
|
720
1053
|
}
|
|
721
1054
|
function ErrorRow({ error }) {
|
|
722
|
-
const [expanded, setExpanded] =
|
|
1055
|
+
const [expanded, setExpanded] = useState3(false);
|
|
723
1056
|
const { styles } = useDevtoolsContext();
|
|
724
1057
|
const containerClass = styles.css`
|
|
725
1058
|
display: block;
|
|
@@ -766,8 +1099,8 @@ function ErrorRow({ error }) {
|
|
|
766
1099
|
`;
|
|
767
1100
|
const displayedStack = truncateStackForDisplay(error.stack);
|
|
768
1101
|
const showDocsLink = typeof error.docsUrl === "string" && error.docsUrl.length > 0;
|
|
769
|
-
return /* @__PURE__ */
|
|
770
|
-
/* @__PURE__ */
|
|
1102
|
+
return /* @__PURE__ */ jsxs4("div", { className: containerClass, "data-testid": "devtools-error-row", children: [
|
|
1103
|
+
/* @__PURE__ */ jsxs4(
|
|
771
1104
|
"button",
|
|
772
1105
|
{
|
|
773
1106
|
type: "button",
|
|
@@ -778,9 +1111,9 @@ function ErrorRow({ error }) {
|
|
|
778
1111
|
"aria-expanded": expanded,
|
|
779
1112
|
title: error.message,
|
|
780
1113
|
children: [
|
|
781
|
-
/* @__PURE__ */
|
|
782
|
-
/* @__PURE__ */
|
|
783
|
-
error.code && /* @__PURE__ */
|
|
1114
|
+
/* @__PURE__ */ jsx6("span", { className: iconClass, "aria-hidden": "true", children: typeIcon(error.type) }),
|
|
1115
|
+
/* @__PURE__ */ jsx6("span", { className: msgClass, children: error.message }),
|
|
1116
|
+
error.code && /* @__PURE__ */ jsx6(
|
|
784
1117
|
"span",
|
|
785
1118
|
{
|
|
786
1119
|
style: {
|
|
@@ -794,8 +1127,8 @@ function ErrorRow({ error }) {
|
|
|
794
1127
|
]
|
|
795
1128
|
}
|
|
796
1129
|
),
|
|
797
|
-
expanded && /* @__PURE__ */
|
|
798
|
-
showDocsLink && /* @__PURE__ */
|
|
1130
|
+
expanded && /* @__PURE__ */ jsxs4("div", { className: detailsClass, children: [
|
|
1131
|
+
showDocsLink && /* @__PURE__ */ jsx6("div", { style: { marginBottom: tokens.spacing.sm }, children: /* @__PURE__ */ jsx6(
|
|
799
1132
|
"a",
|
|
800
1133
|
{
|
|
801
1134
|
href: error.docsUrl,
|
|
@@ -805,7 +1138,7 @@ function ErrorRow({ error }) {
|
|
|
805
1138
|
children: "Open migration guide"
|
|
806
1139
|
}
|
|
807
1140
|
) }),
|
|
808
|
-
displayedStack && /* @__PURE__ */
|
|
1141
|
+
displayedStack && /* @__PURE__ */ jsx6(
|
|
809
1142
|
"pre",
|
|
810
1143
|
{
|
|
811
1144
|
style: {
|
|
@@ -829,11 +1162,11 @@ function ErrorRow({ error }) {
|
|
|
829
1162
|
}
|
|
830
1163
|
|
|
831
1164
|
// src/devtools/components/Tabs/ErrorsTab.tsx
|
|
832
|
-
import { jsx as
|
|
1165
|
+
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
833
1166
|
function ErrorsTab() {
|
|
834
1167
|
const { state, dispatch, styles } = useDevtoolsContext();
|
|
835
1168
|
if (state.errors.length === 0) {
|
|
836
|
-
return /* @__PURE__ */
|
|
1169
|
+
return /* @__PURE__ */ jsx7("div", { style: { color: tokens.colors.textMuted, padding: tokens.spacing.md }, children: "No errors yet. csrf.warn, console.error and unhandled rejections will surface here." });
|
|
837
1170
|
}
|
|
838
1171
|
const headerClass = styles.css`
|
|
839
1172
|
display: flex;
|
|
@@ -855,14 +1188,14 @@ function ErrorsTab() {
|
|
|
855
1188
|
font-size: ${tokens.font.sizeXs};
|
|
856
1189
|
&:hover { color: ${tokens.colors.text}; }
|
|
857
1190
|
`;
|
|
858
|
-
return /* @__PURE__ */
|
|
859
|
-
/* @__PURE__ */
|
|
860
|
-
/* @__PURE__ */
|
|
1191
|
+
return /* @__PURE__ */ jsxs5("div", { "data-testid": "devtools-errors-tab", children: [
|
|
1192
|
+
/* @__PURE__ */ jsxs5("div", { className: headerClass, children: [
|
|
1193
|
+
/* @__PURE__ */ jsxs5("span", { children: [
|
|
861
1194
|
state.errors.length,
|
|
862
1195
|
" error",
|
|
863
1196
|
state.errors.length === 1 ? "" : "s"
|
|
864
1197
|
] }),
|
|
865
|
-
/* @__PURE__ */
|
|
1198
|
+
/* @__PURE__ */ jsx7(
|
|
866
1199
|
"button",
|
|
867
1200
|
{
|
|
868
1201
|
type: "button",
|
|
@@ -874,16 +1207,16 @@ function ErrorsTab() {
|
|
|
874
1207
|
}
|
|
875
1208
|
)
|
|
876
1209
|
] }),
|
|
877
|
-
state.errors.map((err) => /* @__PURE__ */
|
|
1210
|
+
state.errors.map((err) => /* @__PURE__ */ jsx7(ErrorRow, { error: err }, err.id))
|
|
878
1211
|
] });
|
|
879
1212
|
}
|
|
880
1213
|
|
|
881
1214
|
// src/devtools/components/RequestRow.tsx
|
|
882
|
-
import { useState as
|
|
1215
|
+
import { useState as useState5 } from "react";
|
|
883
1216
|
|
|
884
1217
|
// src/devtools/components/JSONExplorer.tsx
|
|
885
|
-
import { useState as
|
|
886
|
-
import { jsx as
|
|
1218
|
+
import { useState as useState4 } from "react";
|
|
1219
|
+
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
887
1220
|
var PAGE_SIZE = 100;
|
|
888
1221
|
var MAX_STRING_DISPLAY = 256;
|
|
889
1222
|
function describe(value) {
|
|
@@ -905,8 +1238,8 @@ function JSONExplorer({
|
|
|
905
1238
|
defaultExpanded = false,
|
|
906
1239
|
depth = 0
|
|
907
1240
|
}) {
|
|
908
|
-
const [expanded, setExpanded] =
|
|
909
|
-
const [pageIndex, setPageIndex] =
|
|
1241
|
+
const [expanded, setExpanded] = useState4(defaultExpanded);
|
|
1242
|
+
const [pageIndex, setPageIndex] = useState4(0);
|
|
910
1243
|
const { styles } = useDevtoolsContext();
|
|
911
1244
|
const rowClass = styles.css`
|
|
912
1245
|
font-family: ${tokens.font.mono};
|
|
@@ -931,26 +1264,26 @@ function JSONExplorer({
|
|
|
931
1264
|
const keyClass = styles.css`color: ${tokens.colors.accent};`;
|
|
932
1265
|
const valClass = styles.css`color: ${tokens.colors.textMuted};`;
|
|
933
1266
|
if (value === null || value === void 0 || typeof value !== "object") {
|
|
934
|
-
return /* @__PURE__ */
|
|
935
|
-
/* @__PURE__ */
|
|
1267
|
+
return /* @__PURE__ */ jsxs6("div", { className: rowClass, children: [
|
|
1268
|
+
/* @__PURE__ */ jsx8("span", { className: keyClass, children: label }),
|
|
936
1269
|
":",
|
|
937
1270
|
" ",
|
|
938
|
-
/* @__PURE__ */
|
|
1271
|
+
/* @__PURE__ */ jsx8("span", { className: valClass, children: describe(value) })
|
|
939
1272
|
] });
|
|
940
1273
|
}
|
|
941
1274
|
const entries = Array.isArray(value) ? value.map((v, i) => [String(i), v]) : Object.entries(value);
|
|
942
1275
|
if (entries.length === 0) {
|
|
943
|
-
return /* @__PURE__ */
|
|
944
|
-
/* @__PURE__ */
|
|
1276
|
+
return /* @__PURE__ */ jsxs6("div", { className: rowClass, children: [
|
|
1277
|
+
/* @__PURE__ */ jsx8("span", { className: keyClass, children: label }),
|
|
945
1278
|
":",
|
|
946
1279
|
" ",
|
|
947
|
-
/* @__PURE__ */
|
|
1280
|
+
/* @__PURE__ */ jsx8("span", { className: valClass, children: Array.isArray(value) ? "[]" : "{}" })
|
|
948
1281
|
] });
|
|
949
1282
|
}
|
|
950
1283
|
const totalPages = Math.ceil(entries.length / PAGE_SIZE);
|
|
951
1284
|
const slice = entries.slice(pageIndex * PAGE_SIZE, (pageIndex + 1) * PAGE_SIZE);
|
|
952
|
-
return /* @__PURE__ */
|
|
953
|
-
/* @__PURE__ */
|
|
1285
|
+
return /* @__PURE__ */ jsxs6("div", { className: rowClass, children: [
|
|
1286
|
+
/* @__PURE__ */ jsxs6(
|
|
954
1287
|
"button",
|
|
955
1288
|
{
|
|
956
1289
|
type: "button",
|
|
@@ -960,15 +1293,15 @@ function JSONExplorer({
|
|
|
960
1293
|
},
|
|
961
1294
|
"aria-expanded": expanded,
|
|
962
1295
|
children: [
|
|
963
|
-
/* @__PURE__ */
|
|
964
|
-
/* @__PURE__ */
|
|
965
|
-
/* @__PURE__ */
|
|
1296
|
+
/* @__PURE__ */ jsx8("span", { children: expanded ? "\u25BE" : "\u25B8" }),
|
|
1297
|
+
/* @__PURE__ */ jsx8("span", { className: keyClass, children: label }),
|
|
1298
|
+
/* @__PURE__ */ jsx8("span", { className: valClass, children: describe(value) })
|
|
966
1299
|
]
|
|
967
1300
|
}
|
|
968
1301
|
),
|
|
969
|
-
expanded && /* @__PURE__ */
|
|
970
|
-
slice.map(([k, v]) => /* @__PURE__ */
|
|
971
|
-
totalPages > 1 && /* @__PURE__ */
|
|
1302
|
+
expanded && /* @__PURE__ */ jsxs6("div", { children: [
|
|
1303
|
+
slice.map(([k, v]) => /* @__PURE__ */ jsx8(JSONExplorer, { label: k, value: v, depth: depth + 1 }, k)),
|
|
1304
|
+
totalPages > 1 && /* @__PURE__ */ jsxs6(
|
|
972
1305
|
"div",
|
|
973
1306
|
{
|
|
974
1307
|
className: styles.css`padding-left: ${(depth + 1) * 12}px; color: ${tokens.colors.textMuted}; font-size: ${tokens.font.sizeXs};`,
|
|
@@ -977,7 +1310,7 @@ function JSONExplorer({
|
|
|
977
1310
|
pageIndex + 1,
|
|
978
1311
|
"/",
|
|
979
1312
|
totalPages,
|
|
980
|
-
pageIndex > 0 && /* @__PURE__ */
|
|
1313
|
+
pageIndex > 0 && /* @__PURE__ */ jsx8(
|
|
981
1314
|
"button",
|
|
982
1315
|
{
|
|
983
1316
|
type: "button",
|
|
@@ -988,7 +1321,7 @@ function JSONExplorer({
|
|
|
988
1321
|
children: "prev"
|
|
989
1322
|
}
|
|
990
1323
|
),
|
|
991
|
-
pageIndex < totalPages - 1 && /* @__PURE__ */
|
|
1324
|
+
pageIndex < totalPages - 1 && /* @__PURE__ */ jsx8(
|
|
992
1325
|
"button",
|
|
993
1326
|
{
|
|
994
1327
|
type: "button",
|
|
@@ -1007,7 +1340,7 @@ function JSONExplorer({
|
|
|
1007
1340
|
}
|
|
1008
1341
|
|
|
1009
1342
|
// src/devtools/components/RequestRow.tsx
|
|
1010
|
-
import { jsx as
|
|
1343
|
+
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1011
1344
|
function buildRequestRowStyles(styles, request) {
|
|
1012
1345
|
return {
|
|
1013
1346
|
container: styles.css`
|
|
@@ -1083,7 +1416,7 @@ function formatDuration(ms) {
|
|
|
1083
1416
|
return `${Math.round(ms)}ms`;
|
|
1084
1417
|
}
|
|
1085
1418
|
function RequestRow({ request }) {
|
|
1086
|
-
const [expanded, setExpanded] =
|
|
1419
|
+
const [expanded, setExpanded] = useState5(false);
|
|
1087
1420
|
const { styles } = useDevtoolsContext();
|
|
1088
1421
|
const cls = buildRequestRowStyles(styles, request);
|
|
1089
1422
|
const containerClass = cls.container;
|
|
@@ -1096,8 +1429,8 @@ function RequestRow({ request }) {
|
|
|
1096
1429
|
const detailsClass = cls.details;
|
|
1097
1430
|
const displayDuration = formatDuration(request.durationMs);
|
|
1098
1431
|
const displayStatus = request.status === 0 ? "failed" : String(request.status);
|
|
1099
|
-
return /* @__PURE__ */
|
|
1100
|
-
/* @__PURE__ */
|
|
1432
|
+
return /* @__PURE__ */ jsxs7("div", { className: containerClass, "data-testid": "devtools-request-row", children: [
|
|
1433
|
+
/* @__PURE__ */ jsxs7(
|
|
1101
1434
|
"button",
|
|
1102
1435
|
{
|
|
1103
1436
|
type: "button",
|
|
@@ -1108,19 +1441,19 @@ function RequestRow({ request }) {
|
|
|
1108
1441
|
"aria-expanded": expanded,
|
|
1109
1442
|
title: request.path,
|
|
1110
1443
|
children: [
|
|
1111
|
-
/* @__PURE__ */
|
|
1112
|
-
/* @__PURE__ */
|
|
1113
|
-
/* @__PURE__ */
|
|
1114
|
-
/* @__PURE__ */
|
|
1115
|
-
/* @__PURE__ */
|
|
1444
|
+
/* @__PURE__ */ jsx9("span", { className: methodBadge, children: request.method }),
|
|
1445
|
+
/* @__PURE__ */ jsx9("span", { className: pathClass, children: request.path }),
|
|
1446
|
+
/* @__PURE__ */ jsx9("span", { className: statusClass, children: displayStatus }),
|
|
1447
|
+
/* @__PURE__ */ jsx9("span", { className: durClass, children: displayDuration }),
|
|
1448
|
+
/* @__PURE__ */ jsx9("span", { className: traceClass, children: request.traceId.slice(0, 8) })
|
|
1116
1449
|
]
|
|
1117
1450
|
}
|
|
1118
1451
|
),
|
|
1119
|
-
expanded && /* @__PURE__ */
|
|
1120
|
-
request.csrfWarn && /* @__PURE__ */
|
|
1452
|
+
expanded && /* @__PURE__ */ jsxs7("div", { className: detailsClass, children: [
|
|
1453
|
+
request.csrfWarn && /* @__PURE__ */ jsxs7("div", { style: { color: tokens.colors.error.csrf, marginBottom: tokens.spacing.sm }, children: [
|
|
1121
1454
|
"CSRF warn:",
|
|
1122
1455
|
" ",
|
|
1123
|
-
/* @__PURE__ */
|
|
1456
|
+
/* @__PURE__ */ jsx9(
|
|
1124
1457
|
"a",
|
|
1125
1458
|
{
|
|
1126
1459
|
href: request.csrfWarn.docsUrl,
|
|
@@ -1131,8 +1464,8 @@ function RequestRow({ request }) {
|
|
|
1131
1464
|
}
|
|
1132
1465
|
)
|
|
1133
1466
|
] }),
|
|
1134
|
-
request.headers && /* @__PURE__ */
|
|
1135
|
-
request.bodyPreview !== void 0 && request.bodyPreview !== "" && /* @__PURE__ */
|
|
1467
|
+
request.headers && /* @__PURE__ */ jsx9(JSONExplorer, { label: "headers", value: request.headers, defaultExpanded: false }),
|
|
1468
|
+
request.bodyPreview !== void 0 && request.bodyPreview !== "" && /* @__PURE__ */ jsxs7(
|
|
1136
1469
|
"div",
|
|
1137
1470
|
{
|
|
1138
1471
|
style: {
|
|
@@ -1145,7 +1478,7 @@ function RequestRow({ request }) {
|
|
|
1145
1478
|
"body",
|
|
1146
1479
|
request.bodyTruncated ? ` (truncated, ${request.bodyLength} bytes)` : "",
|
|
1147
1480
|
":",
|
|
1148
|
-
/* @__PURE__ */
|
|
1481
|
+
/* @__PURE__ */ jsx9("pre", { style: { marginTop: 4, whiteSpace: "pre-wrap", wordBreak: "break-all" }, children: request.bodyPreview })
|
|
1149
1482
|
]
|
|
1150
1483
|
}
|
|
1151
1484
|
)
|
|
@@ -1154,11 +1487,11 @@ function RequestRow({ request }) {
|
|
|
1154
1487
|
}
|
|
1155
1488
|
|
|
1156
1489
|
// src/devtools/components/Tabs/RequestsTab.tsx
|
|
1157
|
-
import { jsx as
|
|
1490
|
+
import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1158
1491
|
function RequestsTab() {
|
|
1159
1492
|
const { state, dispatch, styles } = useDevtoolsContext();
|
|
1160
1493
|
if (state.requests.length === 0) {
|
|
1161
|
-
return /* @__PURE__ */
|
|
1494
|
+
return /* @__PURE__ */ jsx10("div", { style: { color: tokens.colors.textMuted, padding: tokens.spacing.md }, children: "No requests yet. Make a fetch call in your app to see it here." });
|
|
1162
1495
|
}
|
|
1163
1496
|
const headerClass = styles.css`
|
|
1164
1497
|
display: flex;
|
|
@@ -1180,14 +1513,14 @@ function RequestsTab() {
|
|
|
1180
1513
|
font-size: ${tokens.font.sizeXs};
|
|
1181
1514
|
&:hover { color: ${tokens.colors.text}; }
|
|
1182
1515
|
`;
|
|
1183
|
-
return /* @__PURE__ */
|
|
1184
|
-
/* @__PURE__ */
|
|
1185
|
-
/* @__PURE__ */
|
|
1516
|
+
return /* @__PURE__ */ jsxs8("div", { "data-testid": "devtools-requests-tab", children: [
|
|
1517
|
+
/* @__PURE__ */ jsxs8("div", { className: headerClass, children: [
|
|
1518
|
+
/* @__PURE__ */ jsxs8("span", { children: [
|
|
1186
1519
|
state.requests.length,
|
|
1187
1520
|
" request",
|
|
1188
1521
|
state.requests.length === 1 ? "" : "s"
|
|
1189
1522
|
] }),
|
|
1190
|
-
/* @__PURE__ */
|
|
1523
|
+
/* @__PURE__ */ jsx10(
|
|
1191
1524
|
"button",
|
|
1192
1525
|
{
|
|
1193
1526
|
type: "button",
|
|
@@ -1199,16 +1532,16 @@ function RequestsTab() {
|
|
|
1199
1532
|
}
|
|
1200
1533
|
)
|
|
1201
1534
|
] }),
|
|
1202
|
-
state.requests.map((req) => /* @__PURE__ */
|
|
1535
|
+
state.requests.map((req) => /* @__PURE__ */ jsx10(RequestRow, { request: req }, req.id))
|
|
1203
1536
|
] });
|
|
1204
1537
|
}
|
|
1205
1538
|
|
|
1206
1539
|
// src/devtools/components/Tabs/RoutesTab.tsx
|
|
1207
|
-
import { jsx as
|
|
1540
|
+
import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1208
1541
|
function RoutesTab() {
|
|
1209
1542
|
const { state, styles } = useDevtoolsContext();
|
|
1210
1543
|
if (!state.routeManifest || state.routeManifest.routes.length === 0) {
|
|
1211
|
-
return /* @__PURE__ */
|
|
1544
|
+
return /* @__PURE__ */ jsx11("div", { style: { color: tokens.colors.textMuted, padding: tokens.spacing.md }, children: "Routes will appear when the manifest loads." });
|
|
1212
1545
|
}
|
|
1213
1546
|
const rowClass = styles.css`
|
|
1214
1547
|
display: flex;
|
|
@@ -1237,9 +1570,9 @@ function RoutesTab() {
|
|
|
1237
1570
|
console.warn("[theo devtools] Editor not configured");
|
|
1238
1571
|
});
|
|
1239
1572
|
}
|
|
1240
|
-
return /* @__PURE__ */
|
|
1573
|
+
return /* @__PURE__ */ jsx11("div", { "data-testid": "devtools-routes-tab", children: state.routeManifest.routes.map((route) => {
|
|
1241
1574
|
const active = state.activeRoutePath === route.path || state.activeChain.includes(route.absoluteFilePath);
|
|
1242
|
-
return /* @__PURE__ */
|
|
1575
|
+
return /* @__PURE__ */ jsxs9(
|
|
1243
1576
|
"button",
|
|
1244
1577
|
{
|
|
1245
1578
|
type: "button",
|
|
@@ -1250,7 +1583,7 @@ function RoutesTab() {
|
|
|
1250
1583
|
},
|
|
1251
1584
|
title: `Open ${route.absoluteFilePath} in editor`,
|
|
1252
1585
|
children: [
|
|
1253
|
-
/* @__PURE__ */
|
|
1586
|
+
/* @__PURE__ */ jsx11(
|
|
1254
1587
|
"span",
|
|
1255
1588
|
{
|
|
1256
1589
|
style: {
|
|
@@ -1260,8 +1593,8 @@ function RoutesTab() {
|
|
|
1260
1593
|
children: active ? "\u25B8" : " "
|
|
1261
1594
|
}
|
|
1262
1595
|
),
|
|
1263
|
-
/* @__PURE__ */
|
|
1264
|
-
/* @__PURE__ */
|
|
1596
|
+
/* @__PURE__ */ jsx11("span", { style: { flex: 1 }, children: route.path }),
|
|
1597
|
+
/* @__PURE__ */ jsx11("span", { style: { color: tokens.colors.textDim, fontSize: tokens.font.sizeXs }, children: route.absoluteFilePath.split("/").slice(-2).join("/") })
|
|
1265
1598
|
]
|
|
1266
1599
|
},
|
|
1267
1600
|
route.absoluteFilePath
|
|
@@ -1270,7 +1603,7 @@ function RoutesTab() {
|
|
|
1270
1603
|
}
|
|
1271
1604
|
|
|
1272
1605
|
// src/devtools/components/Tabs/SettingsTab.tsx
|
|
1273
|
-
import { jsx as
|
|
1606
|
+
import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1274
1607
|
var POSITIONS = ["top-left", "top-right", "bottom-left", "bottom-right"];
|
|
1275
1608
|
var THEMES = ["light", "dark", "system"];
|
|
1276
1609
|
function SettingsTab() {
|
|
@@ -1291,11 +1624,11 @@ function SettingsTab() {
|
|
|
1291
1624
|
color: ${tokens.colors.text};
|
|
1292
1625
|
font-size: ${tokens.font.sizeSm};
|
|
1293
1626
|
`;
|
|
1294
|
-
return /* @__PURE__ */
|
|
1295
|
-
/* @__PURE__ */
|
|
1296
|
-
/* @__PURE__ */
|
|
1297
|
-
POSITIONS.map((p) => /* @__PURE__ */
|
|
1298
|
-
/* @__PURE__ */
|
|
1627
|
+
return /* @__PURE__ */ jsxs10("div", { "data-testid": "devtools-settings-tab", style: { padding: tokens.spacing.md }, children: [
|
|
1628
|
+
/* @__PURE__ */ jsxs10("fieldset", { className: sectionClass, style: { border: 0, padding: 0, margin: 0 }, children: [
|
|
1629
|
+
/* @__PURE__ */ jsx12("legend", { className: headingClass, children: "Position" }),
|
|
1630
|
+
POSITIONS.map((p) => /* @__PURE__ */ jsxs10("label", { className: radioRowClass, children: [
|
|
1631
|
+
/* @__PURE__ */ jsx12(
|
|
1299
1632
|
"input",
|
|
1300
1633
|
{
|
|
1301
1634
|
type: "radio",
|
|
@@ -1307,13 +1640,13 @@ function SettingsTab() {
|
|
|
1307
1640
|
}
|
|
1308
1641
|
}
|
|
1309
1642
|
),
|
|
1310
|
-
/* @__PURE__ */
|
|
1643
|
+
/* @__PURE__ */ jsx12("span", { children: p })
|
|
1311
1644
|
] }, p))
|
|
1312
1645
|
] }),
|
|
1313
|
-
/* @__PURE__ */
|
|
1314
|
-
/* @__PURE__ */
|
|
1315
|
-
THEMES.map((t) => /* @__PURE__ */
|
|
1316
|
-
/* @__PURE__ */
|
|
1646
|
+
/* @__PURE__ */ jsxs10("fieldset", { className: sectionClass, style: { border: 0, padding: 0, margin: 0 }, children: [
|
|
1647
|
+
/* @__PURE__ */ jsx12("legend", { className: headingClass, children: "Theme" }),
|
|
1648
|
+
THEMES.map((t) => /* @__PURE__ */ jsxs10("label", { className: radioRowClass, children: [
|
|
1649
|
+
/* @__PURE__ */ jsx12(
|
|
1317
1650
|
"input",
|
|
1318
1651
|
{
|
|
1319
1652
|
type: "radio",
|
|
@@ -1325,18 +1658,19 @@ function SettingsTab() {
|
|
|
1325
1658
|
}
|
|
1326
1659
|
}
|
|
1327
1660
|
),
|
|
1328
|
-
/* @__PURE__ */
|
|
1661
|
+
/* @__PURE__ */ jsx12("span", { children: t })
|
|
1329
1662
|
] }, t))
|
|
1330
1663
|
] })
|
|
1331
1664
|
] });
|
|
1332
1665
|
}
|
|
1333
1666
|
|
|
1334
1667
|
// src/devtools/components/Panel.tsx
|
|
1335
|
-
import { jsx as
|
|
1668
|
+
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1336
1669
|
var TABS = [
|
|
1337
1670
|
"requests",
|
|
1338
1671
|
"routes",
|
|
1339
1672
|
"agents",
|
|
1673
|
+
"actions",
|
|
1340
1674
|
"errors",
|
|
1341
1675
|
"csrf-readiness",
|
|
1342
1676
|
"settings"
|
|
@@ -1425,7 +1759,7 @@ function Panel() {
|
|
|
1425
1759
|
const tabBtnClass = cls.tabBtn;
|
|
1426
1760
|
const closeBtnClass = cls.closeBtn;
|
|
1427
1761
|
const bodyClass = cls.body;
|
|
1428
|
-
return /* @__PURE__ */
|
|
1762
|
+
return /* @__PURE__ */ jsxs11(
|
|
1429
1763
|
"div",
|
|
1430
1764
|
{
|
|
1431
1765
|
role: "dialog",
|
|
@@ -1433,9 +1767,9 @@ function Panel() {
|
|
|
1433
1767
|
"data-theo-devtools-panel": "",
|
|
1434
1768
|
className: panelClass,
|
|
1435
1769
|
children: [
|
|
1436
|
-
/* @__PURE__ */
|
|
1437
|
-
/* @__PURE__ */
|
|
1438
|
-
/* @__PURE__ */
|
|
1770
|
+
/* @__PURE__ */ jsxs11("div", { className: headerClass, children: [
|
|
1771
|
+
/* @__PURE__ */ jsxs11("div", { className: tabsClass, role: "tablist", children: [
|
|
1772
|
+
/* @__PURE__ */ jsx13(
|
|
1439
1773
|
"span",
|
|
1440
1774
|
{
|
|
1441
1775
|
className: styles.css`
|
|
@@ -1445,10 +1779,10 @@ function Panel() {
|
|
|
1445
1779
|
opacity: 0.9;
|
|
1446
1780
|
`,
|
|
1447
1781
|
"aria-hidden": "true",
|
|
1448
|
-
children: /* @__PURE__ */
|
|
1782
|
+
children: /* @__PURE__ */ jsx13(TheoLogo, { size: 16 })
|
|
1449
1783
|
}
|
|
1450
1784
|
),
|
|
1451
|
-
TABS.map((t) => /* @__PURE__ */
|
|
1785
|
+
TABS.map((t) => /* @__PURE__ */ jsx13(
|
|
1452
1786
|
"button",
|
|
1453
1787
|
{
|
|
1454
1788
|
type: "button",
|
|
@@ -1464,7 +1798,7 @@ function Panel() {
|
|
|
1464
1798
|
t
|
|
1465
1799
|
))
|
|
1466
1800
|
] }),
|
|
1467
|
-
/* @__PURE__ */
|
|
1801
|
+
/* @__PURE__ */ jsx13(
|
|
1468
1802
|
"button",
|
|
1469
1803
|
{
|
|
1470
1804
|
type: "button",
|
|
@@ -1477,13 +1811,14 @@ function Panel() {
|
|
|
1477
1811
|
}
|
|
1478
1812
|
)
|
|
1479
1813
|
] }),
|
|
1480
|
-
/* @__PURE__ */
|
|
1481
|
-
state.activeTab === "requests" && /* @__PURE__ */
|
|
1482
|
-
state.activeTab === "routes" && /* @__PURE__ */
|
|
1483
|
-
state.activeTab === "agents" && /* @__PURE__ */
|
|
1484
|
-
state.activeTab === "
|
|
1485
|
-
state.activeTab === "
|
|
1486
|
-
state.activeTab === "
|
|
1814
|
+
/* @__PURE__ */ jsxs11("div", { className: bodyClass, "data-testid": "devtools-tab-body", children: [
|
|
1815
|
+
state.activeTab === "requests" && /* @__PURE__ */ jsx13(RequestsTab, {}),
|
|
1816
|
+
state.activeTab === "routes" && /* @__PURE__ */ jsx13(RoutesTab, {}),
|
|
1817
|
+
state.activeTab === "agents" && /* @__PURE__ */ jsx13(AgentsTab, {}),
|
|
1818
|
+
state.activeTab === "actions" && /* @__PURE__ */ jsx13(ActionsTab, {}),
|
|
1819
|
+
state.activeTab === "errors" && /* @__PURE__ */ jsx13(ErrorsTab, {}),
|
|
1820
|
+
state.activeTab === "csrf-readiness" && /* @__PURE__ */ jsx13(CsrfReadinessTab, {}),
|
|
1821
|
+
state.activeTab === "settings" && /* @__PURE__ */ jsx13(SettingsTab, {})
|
|
1487
1822
|
] })
|
|
1488
1823
|
]
|
|
1489
1824
|
}
|
|
@@ -1619,13 +1954,13 @@ function useActiveRoute() {
|
|
|
1619
1954
|
}
|
|
1620
1955
|
|
|
1621
1956
|
// src/devtools/hooks/useResolvedTheme.ts
|
|
1622
|
-
import { useEffect as useEffect4, useState as
|
|
1957
|
+
import { useEffect as useEffect4, useState as useState6 } from "react";
|
|
1623
1958
|
function getSystemTheme() {
|
|
1624
1959
|
if (typeof window === "undefined") return "dark";
|
|
1625
1960
|
return window.matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark";
|
|
1626
1961
|
}
|
|
1627
1962
|
function useResolvedTheme(theme) {
|
|
1628
|
-
const [systemTheme, setSystemTheme] =
|
|
1963
|
+
const [systemTheme, setSystemTheme] = useState6(() => getSystemTheme());
|
|
1629
1964
|
useEffect4(() => {
|
|
1630
1965
|
if (theme !== "system") return;
|
|
1631
1966
|
if (typeof window === "undefined") return;
|
|
@@ -1682,6 +2017,16 @@ function useShortcuts() {
|
|
|
1682
2017
|
}, [dispatch, state.open]);
|
|
1683
2018
|
}
|
|
1684
2019
|
|
|
2020
|
+
// src/devtools/install-global.ts
|
|
2021
|
+
function noopCleanup() {
|
|
2022
|
+
}
|
|
2023
|
+
function installDispatcherGlobal() {
|
|
2024
|
+
if (typeof window === "undefined") return noopCleanup;
|
|
2025
|
+
const w = window;
|
|
2026
|
+
w.__theoDevtoolsDispatcher = dispatcher;
|
|
2027
|
+
return noopCleanup;
|
|
2028
|
+
}
|
|
2029
|
+
|
|
1685
2030
|
// src/devtools/persistence.ts
|
|
1686
2031
|
var STORAGE_KEYS = {
|
|
1687
2032
|
version: "theo-devtools-storage-version",
|
|
@@ -1773,6 +2118,45 @@ function writeToStorage(s) {
|
|
|
1773
2118
|
function appendCapped(arr, item, cap = RING_BUFFER_CAP) {
|
|
1774
2119
|
return [item, ...arr].slice(0, cap);
|
|
1775
2120
|
}
|
|
2121
|
+
function reduceAppend(state, action) {
|
|
2122
|
+
switch (action.type) {
|
|
2123
|
+
case "REQUEST_ADD":
|
|
2124
|
+
return { ...state, requests: appendCapped(state.requests, action.request) };
|
|
2125
|
+
case "ERROR_ADD":
|
|
2126
|
+
return { ...state, errors: appendCapped(state.errors, action.error) };
|
|
2127
|
+
case "AGENT_RUN_ADD":
|
|
2128
|
+
return { ...state, agentRuns: appendCapped(state.agentRuns, action.run) };
|
|
2129
|
+
case "ACTION_CALL_ADD":
|
|
2130
|
+
return { ...state, actionCalls: appendCapped(state.actionCalls, action.record) };
|
|
2131
|
+
default:
|
|
2132
|
+
return null;
|
|
2133
|
+
}
|
|
2134
|
+
}
|
|
2135
|
+
function reduceReset(state, action) {
|
|
2136
|
+
switch (action.type) {
|
|
2137
|
+
case "RESET_REQUESTS":
|
|
2138
|
+
return { ...state, requests: [] };
|
|
2139
|
+
case "RESET_ERRORS":
|
|
2140
|
+
return { ...state, errors: [] };
|
|
2141
|
+
case "RESET_AGENT_RUNS":
|
|
2142
|
+
return { ...state, agentRuns: [] };
|
|
2143
|
+
case "RESET_ACTION_CALLS":
|
|
2144
|
+
return { ...state, actionCalls: [] };
|
|
2145
|
+
default:
|
|
2146
|
+
return null;
|
|
2147
|
+
}
|
|
2148
|
+
}
|
|
2149
|
+
function csrfWarnToErrorRecord(payload) {
|
|
2150
|
+
return {
|
|
2151
|
+
// eslint-disable-next-line sonarjs/pseudo-random -- non-secret correlation id for devtools UI
|
|
2152
|
+
id: `csrf-${String(Date.now())}-${Math.random().toString(36).slice(2, 8)}`,
|
|
2153
|
+
type: "csrf.warn",
|
|
2154
|
+
message: `CSRF warn: ${payload.method} ${payload.path} \u2014 ${payload.reason}`,
|
|
2155
|
+
code: payload.code,
|
|
2156
|
+
docsUrl: payload.docsUrl,
|
|
2157
|
+
timestamp: Date.now()
|
|
2158
|
+
};
|
|
2159
|
+
}
|
|
1776
2160
|
function devtoolsReducer(state, action) {
|
|
1777
2161
|
switch (action.type) {
|
|
1778
2162
|
case "TOGGLE_PANEL":
|
|
@@ -1785,36 +2169,14 @@ function devtoolsReducer(state, action) {
|
|
|
1785
2169
|
return { ...state, position: action.position };
|
|
1786
2170
|
case "SET_THEME":
|
|
1787
2171
|
return { ...state, theme: action.theme };
|
|
1788
|
-
case "
|
|
1789
|
-
return { ...state,
|
|
1790
|
-
case "ERROR_ADD":
|
|
1791
|
-
return { ...state, errors: appendCapped(state.errors, action.error) };
|
|
1792
|
-
case "CSRF_WARN": {
|
|
1793
|
-
const errorRecord = {
|
|
1794
|
-
// eslint-disable-next-line sonarjs/pseudo-random -- non-secret correlation id for devtools UI
|
|
1795
|
-
id: `csrf-${String(Date.now())}-${Math.random().toString(36).slice(2, 8)}`,
|
|
1796
|
-
type: "csrf.warn",
|
|
1797
|
-
message: `CSRF warn: ${action.payload.method} ${action.payload.path} \u2014 ${action.payload.reason}`,
|
|
1798
|
-
code: action.payload.code,
|
|
1799
|
-
docsUrl: action.payload.docsUrl,
|
|
1800
|
-
timestamp: Date.now()
|
|
1801
|
-
};
|
|
1802
|
-
return { ...state, errors: appendCapped(state.errors, errorRecord) };
|
|
1803
|
-
}
|
|
2172
|
+
case "CSRF_WARN":
|
|
2173
|
+
return { ...state, errors: appendCapped(state.errors, csrfWarnToErrorRecord(action.payload)) };
|
|
1804
2174
|
case "MANIFEST_UPDATED":
|
|
1805
2175
|
return { ...state, routeManifest: action.manifest };
|
|
1806
2176
|
case "ROUTE_MATCHED":
|
|
1807
2177
|
return { ...state, activeRoutePath: action.path, activeChain: action.chain };
|
|
1808
|
-
case "AGENT_RUN_ADD":
|
|
1809
|
-
return { ...state, agentRuns: appendCapped(state.agentRuns, action.run) };
|
|
1810
|
-
case "RESET_REQUESTS":
|
|
1811
|
-
return { ...state, requests: [] };
|
|
1812
|
-
case "RESET_ERRORS":
|
|
1813
|
-
return { ...state, errors: [] };
|
|
1814
|
-
case "RESET_AGENT_RUNS":
|
|
1815
|
-
return { ...state, agentRuns: [] };
|
|
1816
2178
|
default:
|
|
1817
|
-
return state;
|
|
2179
|
+
return reduceAppend(state, action) ?? reduceReset(state, action) ?? state;
|
|
1818
2180
|
}
|
|
1819
2181
|
}
|
|
1820
2182
|
|
|
@@ -1845,7 +2207,7 @@ function createStyles(shadowRoot) {
|
|
|
1845
2207
|
}
|
|
1846
2208
|
|
|
1847
2209
|
// src/devtools/Overlay.tsx
|
|
1848
|
-
import { jsx as
|
|
2210
|
+
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1849
2211
|
function ActiveRouteTracker() {
|
|
1850
2212
|
useActiveRoute();
|
|
1851
2213
|
return null;
|
|
@@ -1856,7 +2218,7 @@ function ShortcutsTracker() {
|
|
|
1856
2218
|
}
|
|
1857
2219
|
function ThemeVars({ resolved }) {
|
|
1858
2220
|
const css = `:host { color-scheme: ${resolved}; ${buildThemeCssVars(resolved)} }`;
|
|
1859
|
-
return /* @__PURE__ */
|
|
2221
|
+
return /* @__PURE__ */ jsx14("style", { "data-theo-devtools-theme": resolved, children: css });
|
|
1860
2222
|
}
|
|
1861
2223
|
function Overlay({ shadowRoot }) {
|
|
1862
2224
|
const [state, dispatch] = useReducer(
|
|
@@ -1878,8 +2240,10 @@ function Overlay({ shadowRoot }) {
|
|
|
1878
2240
|
}, [state.position, state.theme, state.open, state.activeTab, state.visible]);
|
|
1879
2241
|
useInsertionEffect(() => {
|
|
1880
2242
|
dispatcher.setDispatch(dispatch);
|
|
2243
|
+
const uninstall = installDispatcherGlobal();
|
|
1881
2244
|
return () => {
|
|
1882
2245
|
dispatcher.setDispatch(null);
|
|
2246
|
+
uninstall();
|
|
1883
2247
|
};
|
|
1884
2248
|
}, []);
|
|
1885
2249
|
useEffect6(() => {
|
|
@@ -1888,17 +2252,17 @@ function Overlay({ shadowRoot }) {
|
|
|
1888
2252
|
sub.unsubscribe();
|
|
1889
2253
|
};
|
|
1890
2254
|
}, []);
|
|
1891
|
-
return /* @__PURE__ */
|
|
1892
|
-
/* @__PURE__ */
|
|
1893
|
-
/* @__PURE__ */
|
|
1894
|
-
/* @__PURE__ */
|
|
1895
|
-
/* @__PURE__ */
|
|
1896
|
-
/* @__PURE__ */
|
|
2255
|
+
return /* @__PURE__ */ jsx14(DevtoolsContext.Provider, { value: { shadowRoot, state, dispatch, styles }, children: /* @__PURE__ */ jsxs12(ShadowPortal, { children: [
|
|
2256
|
+
/* @__PURE__ */ jsx14(ThemeVars, { resolved: resolvedTheme }),
|
|
2257
|
+
/* @__PURE__ */ jsx14(ActiveRouteTracker, {}),
|
|
2258
|
+
/* @__PURE__ */ jsx14(ShortcutsTracker, {}),
|
|
2259
|
+
/* @__PURE__ */ jsx14(Indicator, {}),
|
|
2260
|
+
/* @__PURE__ */ jsx14(Panel, {})
|
|
1897
2261
|
] }) });
|
|
1898
2262
|
}
|
|
1899
2263
|
|
|
1900
2264
|
// src/devtools/entry.tsx
|
|
1901
|
-
import { jsx as
|
|
2265
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
1902
2266
|
var PORTAL_TAG = "theo-devtools-portal";
|
|
1903
2267
|
function definePortalElement() {
|
|
1904
2268
|
if (typeof customElements === "undefined") return;
|
|
@@ -1925,7 +2289,7 @@ function mount() {
|
|
|
1925
2289
|
shadowRoot.appendChild(reactRootHost);
|
|
1926
2290
|
const root = createRoot(reactRootHost);
|
|
1927
2291
|
root.render(
|
|
1928
|
-
/* @__PURE__ */
|
|
2292
|
+
/* @__PURE__ */ jsx15(StrictMode, { children: /* @__PURE__ */ jsx15(Overlay, { shadowRoot }) })
|
|
1929
2293
|
);
|
|
1930
2294
|
}
|
|
1931
2295
|
if (typeof document !== "undefined") {
|