@almadar/ui 2.10.0 → 2.11.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.
- package/dist/{chunk-N6DJVKZ6.js → chunk-3E73CE7J.js} +260 -1
- package/dist/cn-C_ATNPvi.d.ts +332 -0
- package/dist/components/index.css +88 -0
- package/dist/components/index.d.ts +22 -3
- package/dist/components/index.js +1090 -19
- package/dist/lib/index.d.ts +175 -313
- package/dist/lib/index.js +1 -262
- package/dist/providers/index.js +1 -1
- package/dist/runtime/index.js +1 -1
- package/package.json +1 -1
- package/dist/cn-BoBXsxuX.d.ts +0 -194
package/dist/components/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { DEFAULT_CONFIG, renderStateMachineToDomData, parseContentSegments } from '../chunk-
|
|
1
|
+
import { DEFAULT_CONFIG, renderStateMachineToDomData, parseContentSegments, isDebugEnabled, onDebugToggle, subscribeToTraitChanges, subscribeToTickChanges, subscribeToGuardChanges, subscribeToDebugEvents, getEntitySnapshot, getDebugEvents, getGuardHistory, getAllTicks, getAllTraits } from '../chunk-3E73CE7J.js';
|
|
2
2
|
import { useAuthContext } from '../chunk-GTIAVPI5.js';
|
|
3
3
|
export { ENTITY_EVENTS, useAgentChat, useAuthContext, useCompile, useConnectGitHub, useCreateEntity, useDeepAgentGeneration, useDeleteEntity, useDisconnectGitHub, useEntities, useEntitiesByType, useEntity as useEntityById, useEntityMutations, useExtensions, useFileEditor, useFileSystem, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useInput, useOrbitalHistory, useOrbitalMutations, usePhysics, usePinchZoom, usePlayer, usePreview, useResolvedEntity, useSelectedEntity, useSendOrbitalEvent, useSingletonEntity, useUIEvents, useUpdateEntity, useValidation } from '../chunk-GTIAVPI5.js';
|
|
4
4
|
export { clearEntities, getAllEntities, getByType, getEntity, getSingleton, removeEntity, spawnEntity, updateEntity, updateSingleton } from '../chunk-N7MVUW4R.js';
|
|
5
5
|
import '../chunk-3HJHHULT.js';
|
|
6
|
-
import { VStack, HStack, Typography, Button, Icon, Box, Card, Avatar, Badge, SearchInput, Checkbox, Menu as Menu$1, Pagination, LoadingState, EmptyState, Modal, ErrorState, QuizBlock, CodeBlock, ScaledDiagram, MarkdownContent, Divider, ProgressBar, isoToScreen, IsometricCanvas_default, Stack, Select, Drawer, Toast, Tabs, Input, ThemeToggle, TILE_WIDTH, EntityDisplayEvents, StateIndicator, Container } from '../chunk-7M2KEJTF.js';
|
|
6
|
+
import { VStack, HStack, Typography, Button, Icon, Box, Card, Avatar, Badge, SearchInput, Checkbox, Menu as Menu$1, Pagination, LoadingState, EmptyState, Modal, ErrorState, QuizBlock, CodeBlock, ScaledDiagram, MarkdownContent, Divider, ProgressBar, isoToScreen, IsometricCanvas_default, Stack, Select, Drawer, Toast, Tabs, Input, ThemeToggle, TILE_WIDTH, EntityDisplayEvents, StateIndicator, Accordion, ButtonGroup, Container } from '../chunk-7M2KEJTF.js';
|
|
7
7
|
export { ALL_PRESETS, Accordion, ActionButton, ActionButtons, Card2 as ActionCard, Alert, AnimatedCounter, Avatar, Badge, Box, Breadcrumb, Button, ButtonGroup, CalendarGrid, CanvasEffect, Card, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, Center, Chart, ChartLegend, Checkbox, ChoiceButton, CodeBlock, CombatLog, ComboCounter, ConditionalWrapper, ConfettiEffect, Container, ControlButton, CraftingRecipe, DIAMOND_TOP_Y, DPad, DamageNumber, DataGrid, DataList, DataTable, DateRangeSelector, DayCell, DetailPanel, DialogueBox, DialogueBubble, Divider, Drawer, EmptyState, EnemyPlate, EntityDisplayEvents, ErrorBoundary, ErrorState, FEATURE_COLORS, FLOOR_HEIGHT, FilterGroup, Flex, FlipCard, FlipContainer, FloatingActionButton, Form, FormField, FormSectionHeader, GameCanvas2D, GameHud, GameMenu, GameOverScreen, GraphView, Grid, HStack, Heading, HealthBar, HealthPanel, Icon, InfiniteScrollSentinel, Input, InputGroup, InventoryGrid, InventoryPanel, IsometricCanvas, ItemSlot, Label, LawReferenceTooltip, Lightbox, LineChart, LoadingState, MapView, MarkdownContent, MasterDetail, Menu, Meter, MiniMap, Modal, NumberStepper, Overlay, PageHeader, Pagination, PlatformerCanvas, Popover, PowerupSlots, ProgressBar, ProgressDots, PullToRefresh, QuestTracker, QuizBlock, Radio, RangeSlider, RelationSelect, RepeatableFormSection, ResourceBar, ResourceCounter, ScaledDiagram, ScoreBoard, ScoreDisplay, SearchInput, Select, SidePanel, SimpleGrid, SimulationCanvas, SimulationControls, SimulationGraph, Skeleton, SlotContentRenderer, SortableList, Spacer, Spinner, Sprite, Stack, StarRating, StatBadge, StatCard, StatDisplay, StateIndicator, StatusDot, StatusEffect, SwipeableRow, Switch, TILE_HEIGHT, TILE_WIDTH, Tabs, Text, TextHighlight, Textarea, ThemeSelector, ThemeToggle, TimeSlotCell, TimerDisplay, Toast, Tooltip, TrendIndicator, TurnIndicator, TurnPanel, TypewriterText, Typography, UISlotComponent, UISlotRenderer, UnitCommandBar, UploadDropZone, VStack, ViolationAlert, WaypointMarker, WizardNavigation, WizardProgress, XPBar, drawSprite, isoToScreen, pendulum, projectileMotion, screenToIso, springOscillator, useCamera, useImageCache } from '../chunk-7M2KEJTF.js';
|
|
8
8
|
import '../chunk-DKQN5FVU.js';
|
|
9
9
|
import { useTranslate } from '../chunk-WGJIL4YR.js';
|
|
@@ -11,12 +11,13 @@ export { EntityDataProvider, I18nProvider, createTranslate, entityDataKeys, pars
|
|
|
11
11
|
import { useEventBus, useEventListener } from '../chunk-YXZM3WCF.js';
|
|
12
12
|
export { useEmitEvent, useEventBus, useEventListener } from '../chunk-YXZM3WCF.js';
|
|
13
13
|
export { DEFAULT_SLOTS, useUISlotManager } from '../chunk-3JGAROCW.js';
|
|
14
|
-
import { cn, getNestedValue } from '../chunk-6D5QMEUS.js';
|
|
15
|
-
export { cn } from '../chunk-6D5QMEUS.js';
|
|
16
14
|
import '../chunk-TSETXL2E.js';
|
|
15
|
+
import { cn, getNestedValue, subscribeToVerification, getSummary, getBridgeHealth, getTransitions, getAllChecks } from '../chunk-6D5QMEUS.js';
|
|
16
|
+
export { cn } from '../chunk-6D5QMEUS.js';
|
|
17
17
|
import '../chunk-K2D5D3WK.js';
|
|
18
18
|
import { __publicField } from '../chunk-PKBMQBKP.js';
|
|
19
|
-
import
|
|
19
|
+
import * as React44 from 'react';
|
|
20
|
+
import React44__default, { createContext, useState, useCallback, useMemo, useEffect, useRef, useContext } from 'react';
|
|
20
21
|
import { ChevronDown, X, Menu, ChevronRight, ChevronLeft, ArrowUp, ArrowDown, MoreVertical, Package, Check, AlertTriangle, Trash2, List as List$1, Printer, CheckCircle, XCircle, Play, RotateCcw, Send, Wrench, Bug, ArrowRight, AlertCircle, Circle, Clock, CheckCircle2, Image as Image$1, Upload, ZoomIn, Eraser, FileText, ZoomOut, Download, Code, WrapText, Copy, Settings, Search, Bell, LogOut, Pause, Calendar, Pencil, Eye, MoreHorizontal, Minus, Plus } from 'lucide-react';
|
|
21
22
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
22
23
|
import { createPortal } from 'react-dom';
|
|
@@ -32,7 +33,7 @@ var FormSection = ({
|
|
|
32
33
|
columns = 1,
|
|
33
34
|
className
|
|
34
35
|
}) => {
|
|
35
|
-
const [collapsed, setCollapsed] =
|
|
36
|
+
const [collapsed, setCollapsed] = React44__default.useState(defaultCollapsed);
|
|
36
37
|
const { t } = useTranslate();
|
|
37
38
|
const eventBus = useEventBus();
|
|
38
39
|
const gridClass = {
|
|
@@ -40,7 +41,7 @@ var FormSection = ({
|
|
|
40
41
|
2: "grid-cols-1 md:grid-cols-2",
|
|
41
42
|
3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"
|
|
42
43
|
}[columns];
|
|
43
|
-
|
|
44
|
+
React44__default.useCallback(() => {
|
|
44
45
|
if (collapsible) {
|
|
45
46
|
setCollapsed((prev) => !prev);
|
|
46
47
|
eventBus.emit("UI:TOGGLE_COLLAPSE", { collapsed: !collapsed });
|
|
@@ -1012,7 +1013,7 @@ var List = ({
|
|
|
1012
1013
|
if (entity && typeof entity === "object" && "id" in entity) return [entity];
|
|
1013
1014
|
return [];
|
|
1014
1015
|
}, [entity]);
|
|
1015
|
-
const getItemActions =
|
|
1016
|
+
const getItemActions = React44__default.useCallback(
|
|
1016
1017
|
(item) => {
|
|
1017
1018
|
if (!itemActions) return [];
|
|
1018
1019
|
if (typeof itemActions === "function") {
|
|
@@ -1517,7 +1518,7 @@ var WizardContainer = ({
|
|
|
1517
1518
|
const isCompleted = index < currentStep;
|
|
1518
1519
|
const stepKey = step.id ?? step.tabId ?? `step-${index}`;
|
|
1519
1520
|
const stepTitle = step.title ?? step.name ?? `Step ${index + 1}`;
|
|
1520
|
-
return /* @__PURE__ */ jsxs(
|
|
1521
|
+
return /* @__PURE__ */ jsxs(React44__default.Fragment, { children: [
|
|
1521
1522
|
/* @__PURE__ */ jsx(
|
|
1522
1523
|
Button,
|
|
1523
1524
|
{
|
|
@@ -2741,7 +2742,7 @@ var StateMachineView = ({
|
|
|
2741
2742
|
style: { top: title ? 30 : 0 },
|
|
2742
2743
|
children: [
|
|
2743
2744
|
entity && /* @__PURE__ */ jsx(EntityBox, { entity, config }),
|
|
2744
|
-
states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(
|
|
2745
|
+
states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React44__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
|
|
2745
2746
|
StateNode,
|
|
2746
2747
|
{
|
|
2747
2748
|
state,
|
|
@@ -5410,7 +5411,7 @@ function LinearView({
|
|
|
5410
5411
|
/* @__PURE__ */ jsx(HStack, { className: "flex-wrap items-center", gap: "xs", children: trait.states.map((state, i) => {
|
|
5411
5412
|
const isDone = i < currentIdx;
|
|
5412
5413
|
const isCurrent = i === currentIdx;
|
|
5413
|
-
return /* @__PURE__ */ jsxs(
|
|
5414
|
+
return /* @__PURE__ */ jsxs(React44__default.Fragment, { children: [
|
|
5414
5415
|
i > 0 && /* @__PURE__ */ jsx(
|
|
5415
5416
|
Typography,
|
|
5416
5417
|
{
|
|
@@ -6064,7 +6065,7 @@ function SequenceBar({
|
|
|
6064
6065
|
onSlotRemove(index);
|
|
6065
6066
|
}, [onSlotRemove, playing]);
|
|
6066
6067
|
const paddedSlots = Array.from({ length: maxSlots }, (_, i) => slots[i]);
|
|
6067
|
-
return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(
|
|
6068
|
+
return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React44__default.Fragment, { children: [
|
|
6068
6069
|
i > 0 && /* @__PURE__ */ jsx(
|
|
6069
6070
|
Typography,
|
|
6070
6071
|
{
|
|
@@ -7993,7 +7994,7 @@ function generateCombatMessage(event) {
|
|
|
7993
7994
|
return event.message;
|
|
7994
7995
|
}
|
|
7995
7996
|
function extractTitle(children) {
|
|
7996
|
-
if (!
|
|
7997
|
+
if (!React44__default.isValidElement(children)) return void 0;
|
|
7997
7998
|
const props = children.props;
|
|
7998
7999
|
if (typeof props.title === "string") {
|
|
7999
8000
|
return props.title;
|
|
@@ -8028,7 +8029,7 @@ var ModalSlot = ({
|
|
|
8028
8029
|
};
|
|
8029
8030
|
ModalSlot.displayName = "ModalSlot";
|
|
8030
8031
|
function extractTitle2(children) {
|
|
8031
|
-
if (!
|
|
8032
|
+
if (!React44__default.isValidElement(children)) return void 0;
|
|
8032
8033
|
const props = children.props;
|
|
8033
8034
|
if (typeof props.title === "string") {
|
|
8034
8035
|
return props.title;
|
|
@@ -8065,7 +8066,7 @@ var DrawerSlot = ({
|
|
|
8065
8066
|
};
|
|
8066
8067
|
DrawerSlot.displayName = "DrawerSlot";
|
|
8067
8068
|
function extractToastProps(children) {
|
|
8068
|
-
if (!
|
|
8069
|
+
if (!React44__default.isValidElement(children)) {
|
|
8069
8070
|
if (typeof children === "string") {
|
|
8070
8071
|
return { message: children };
|
|
8071
8072
|
}
|
|
@@ -8096,7 +8097,7 @@ var ToastSlot = ({
|
|
|
8096
8097
|
eventBus.emit("UI:CLOSE");
|
|
8097
8098
|
};
|
|
8098
8099
|
if (!isVisible) return null;
|
|
8099
|
-
const isCustomContent =
|
|
8100
|
+
const isCustomContent = React44__default.isValidElement(children) && !message;
|
|
8100
8101
|
return /* @__PURE__ */ jsx(Box, { className: "fixed bottom-4 right-4 z-50", children: isCustomContent ? children : /* @__PURE__ */ jsx(
|
|
8101
8102
|
Toast,
|
|
8102
8103
|
{
|
|
@@ -8193,7 +8194,7 @@ var Timeline = ({
|
|
|
8193
8194
|
}) => {
|
|
8194
8195
|
const { t } = useTranslate();
|
|
8195
8196
|
const entityData = Array.isArray(entity) ? entity : [];
|
|
8196
|
-
const items =
|
|
8197
|
+
const items = React44__default.useMemo(() => {
|
|
8197
8198
|
if (propItems) return propItems;
|
|
8198
8199
|
if (entityData.length === 0) return [];
|
|
8199
8200
|
return entityData.map((record, idx) => {
|
|
@@ -8334,7 +8335,7 @@ var MediaGallery = ({
|
|
|
8334
8335
|
[selectable, selectedItems, selectionEvent, eventBus]
|
|
8335
8336
|
);
|
|
8336
8337
|
const entityData = Array.isArray(entity) ? entity : [];
|
|
8337
|
-
const items =
|
|
8338
|
+
const items = React44__default.useMemo(() => {
|
|
8338
8339
|
if (propItems) return propItems;
|
|
8339
8340
|
if (entityData.length === 0) return [];
|
|
8340
8341
|
return entityData.map((record, idx) => ({
|
|
@@ -9401,6 +9402,1076 @@ var CodeViewer = ({
|
|
|
9401
9402
|
] }) });
|
|
9402
9403
|
};
|
|
9403
9404
|
CodeViewer.displayName = "CodeViewer";
|
|
9405
|
+
function useDebugData() {
|
|
9406
|
+
const [data, setData] = React44.useState(() => ({
|
|
9407
|
+
traits: [],
|
|
9408
|
+
ticks: [],
|
|
9409
|
+
guards: [],
|
|
9410
|
+
events: [],
|
|
9411
|
+
entitySnapshot: null,
|
|
9412
|
+
verification: {
|
|
9413
|
+
checks: [],
|
|
9414
|
+
transitions: [],
|
|
9415
|
+
bridge: null,
|
|
9416
|
+
summary: { totalChecks: 0, passed: 0, failed: 0, warnings: 0, pending: 0 }
|
|
9417
|
+
},
|
|
9418
|
+
lastUpdate: Date.now()
|
|
9419
|
+
}));
|
|
9420
|
+
React44.useEffect(() => {
|
|
9421
|
+
const updateData = () => {
|
|
9422
|
+
setData({
|
|
9423
|
+
traits: getAllTraits(),
|
|
9424
|
+
ticks: getAllTicks(),
|
|
9425
|
+
guards: getGuardHistory(),
|
|
9426
|
+
events: getDebugEvents(),
|
|
9427
|
+
entitySnapshot: getEntitySnapshot(),
|
|
9428
|
+
verification: {
|
|
9429
|
+
checks: getAllChecks(),
|
|
9430
|
+
transitions: getTransitions(),
|
|
9431
|
+
bridge: getBridgeHealth(),
|
|
9432
|
+
summary: getSummary()
|
|
9433
|
+
},
|
|
9434
|
+
lastUpdate: Date.now()
|
|
9435
|
+
});
|
|
9436
|
+
};
|
|
9437
|
+
updateData();
|
|
9438
|
+
const unsubTraits = subscribeToTraitChanges(updateData);
|
|
9439
|
+
const unsubTicks = subscribeToTickChanges(updateData);
|
|
9440
|
+
const unsubGuards = subscribeToGuardChanges(updateData);
|
|
9441
|
+
const unsubEvents = subscribeToDebugEvents(updateData);
|
|
9442
|
+
const unsubVerification = subscribeToVerification(updateData);
|
|
9443
|
+
const pollInterval = setInterval(() => {
|
|
9444
|
+
setData((prev) => ({
|
|
9445
|
+
...prev,
|
|
9446
|
+
entitySnapshot: getEntitySnapshot(),
|
|
9447
|
+
lastUpdate: Date.now()
|
|
9448
|
+
}));
|
|
9449
|
+
}, 500);
|
|
9450
|
+
return () => {
|
|
9451
|
+
unsubTraits();
|
|
9452
|
+
unsubTicks();
|
|
9453
|
+
unsubGuards();
|
|
9454
|
+
unsubEvents();
|
|
9455
|
+
unsubVerification();
|
|
9456
|
+
clearInterval(pollInterval);
|
|
9457
|
+
};
|
|
9458
|
+
}, []);
|
|
9459
|
+
return data;
|
|
9460
|
+
}
|
|
9461
|
+
function TraitsTab({ traits }) {
|
|
9462
|
+
if (traits.length === 0) {
|
|
9463
|
+
return /* @__PURE__ */ jsx(
|
|
9464
|
+
EmptyState,
|
|
9465
|
+
{
|
|
9466
|
+
title: "No active traits",
|
|
9467
|
+
description: "Traits will appear when components using them are mounted",
|
|
9468
|
+
className: "py-8"
|
|
9469
|
+
}
|
|
9470
|
+
);
|
|
9471
|
+
}
|
|
9472
|
+
const accordionItems = traits.map((trait) => ({
|
|
9473
|
+
id: trait.id,
|
|
9474
|
+
header: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 w-full", children: [
|
|
9475
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "semibold", className: "text-purple-600 dark:text-purple-400", children: trait.name }),
|
|
9476
|
+
/* @__PURE__ */ jsx(Badge, { variant: "success", size: "sm", children: trait.currentState }),
|
|
9477
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "small", className: "text-gray-500 ml-auto", children: [
|
|
9478
|
+
trait.transitionCount,
|
|
9479
|
+
" transitions"
|
|
9480
|
+
] })
|
|
9481
|
+
] }),
|
|
9482
|
+
content: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
9483
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
9484
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "text-gray-500 mb-2", children: "States" }),
|
|
9485
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1", children: trait.states.map((state) => /* @__PURE__ */ jsx(
|
|
9486
|
+
Badge,
|
|
9487
|
+
{
|
|
9488
|
+
variant: state === trait.currentState ? "success" : "default",
|
|
9489
|
+
size: "sm",
|
|
9490
|
+
children: state
|
|
9491
|
+
},
|
|
9492
|
+
state
|
|
9493
|
+
)) })
|
|
9494
|
+
] }),
|
|
9495
|
+
trait.transitions.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
|
|
9496
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "text-gray-500 mb-2", children: "Transitions" }),
|
|
9497
|
+
/* @__PURE__ */ jsx(Stack, { gap: "xs", children: trait.transitions.map((t, i) => /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "font-mono", children: [
|
|
9498
|
+
t.from,
|
|
9499
|
+
" \u2192 ",
|
|
9500
|
+
t.to,
|
|
9501
|
+
" ",
|
|
9502
|
+
/* @__PURE__ */ jsxs("span", { className: "text-gray-500", children: [
|
|
9503
|
+
"(",
|
|
9504
|
+
t.event,
|
|
9505
|
+
")"
|
|
9506
|
+
] }),
|
|
9507
|
+
t.guard && /* @__PURE__ */ jsxs("span", { className: "text-amber-500", children: [
|
|
9508
|
+
" [",
|
|
9509
|
+
t.guard,
|
|
9510
|
+
"]"
|
|
9511
|
+
] })
|
|
9512
|
+
] }, i)) })
|
|
9513
|
+
] }),
|
|
9514
|
+
trait.guards.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
|
|
9515
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "text-gray-500 mb-2", children: "Guards" }),
|
|
9516
|
+
/* @__PURE__ */ jsx(Stack, { gap: "xs", children: trait.guards.map((g, i) => /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
9517
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", children: g.name }),
|
|
9518
|
+
/* @__PURE__ */ jsx(Badge, { variant: g.lastResult === true ? "success" : g.lastResult === false ? "danger" : "default", size: "sm", children: g.lastResult === void 0 ? "?" : g.lastResult ? "\u2713" : "\u2717" })
|
|
9519
|
+
] }, i)) })
|
|
9520
|
+
] })
|
|
9521
|
+
] })
|
|
9522
|
+
}));
|
|
9523
|
+
return /* @__PURE__ */ jsx("div", { className: "debug-tab debug-tab--traits", children: /* @__PURE__ */ jsx(Accordion, { items: accordionItems, multiple: true }) });
|
|
9524
|
+
}
|
|
9525
|
+
TraitsTab.displayName = "TraitsTab";
|
|
9526
|
+
function TicksTab({ ticks }) {
|
|
9527
|
+
const activeTicks = ticks.filter((t) => t.active);
|
|
9528
|
+
const inactiveTicks = ticks.filter((t) => !t.active);
|
|
9529
|
+
if (ticks.length === 0) {
|
|
9530
|
+
return /* @__PURE__ */ jsx(
|
|
9531
|
+
EmptyState,
|
|
9532
|
+
{
|
|
9533
|
+
title: "No ticks registered",
|
|
9534
|
+
description: "Ticks will appear when trait tick handlers are running",
|
|
9535
|
+
className: "py-8"
|
|
9536
|
+
}
|
|
9537
|
+
);
|
|
9538
|
+
}
|
|
9539
|
+
const formatTime = (ms) => {
|
|
9540
|
+
if (ms === 0) return "never";
|
|
9541
|
+
const seconds = Math.floor((Date.now() - ms) / 1e3);
|
|
9542
|
+
if (seconds < 1) return "just now";
|
|
9543
|
+
if (seconds < 60) return `${seconds}s ago`;
|
|
9544
|
+
return `${Math.floor(seconds / 60)}m ago`;
|
|
9545
|
+
};
|
|
9546
|
+
const TickCard = ({ tick, active }) => /* @__PURE__ */ jsxs(Card, { className: `p-3 ${!active ? "opacity-50" : ""}`, children: [
|
|
9547
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-2", children: [
|
|
9548
|
+
/* @__PURE__ */ jsx("span", { className: `w-2 h-2 rounded-full ${active ? "bg-green-500" : "bg-gray-400"}` }),
|
|
9549
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "semibold", className: "text-amber-600 dark:text-amber-400", children: tick.name }),
|
|
9550
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-gray-500", children: tick.traitName })
|
|
9551
|
+
] }),
|
|
9552
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-3 text-xs text-gray-500", children: [
|
|
9553
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
9554
|
+
tick.interval,
|
|
9555
|
+
"ms"
|
|
9556
|
+
] }),
|
|
9557
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
9558
|
+
tick.runCount,
|
|
9559
|
+
" runs"
|
|
9560
|
+
] }),
|
|
9561
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
9562
|
+
tick.executionTime.toFixed(1),
|
|
9563
|
+
"ms exec"
|
|
9564
|
+
] }),
|
|
9565
|
+
/* @__PURE__ */ jsx("span", { children: formatTime(tick.lastRun) })
|
|
9566
|
+
] }),
|
|
9567
|
+
tick.guardName && /* @__PURE__ */ jsx("div", { className: "mt-2", children: /* @__PURE__ */ jsxs(Badge, { variant: tick.guardPassed ? "success" : "danger", size: "sm", children: [
|
|
9568
|
+
tick.guardName,
|
|
9569
|
+
": ",
|
|
9570
|
+
tick.guardPassed ? "\u2713" : "\u2717"
|
|
9571
|
+
] }) })
|
|
9572
|
+
] });
|
|
9573
|
+
return /* @__PURE__ */ jsxs("div", { className: "debug-tab debug-tab--ticks", children: [
|
|
9574
|
+
activeTicks.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
9575
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "small", weight: "medium", className: "text-gray-500 mb-2", children: [
|
|
9576
|
+
"Active (",
|
|
9577
|
+
activeTicks.length,
|
|
9578
|
+
")"
|
|
9579
|
+
] }),
|
|
9580
|
+
/* @__PURE__ */ jsx(Stack, { gap: "sm", children: activeTicks.map((tick) => /* @__PURE__ */ jsx(TickCard, { tick, active: true }, tick.id)) })
|
|
9581
|
+
] }),
|
|
9582
|
+
inactiveTicks.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
|
|
9583
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "small", weight: "medium", className: "text-gray-400 mb-2", children: [
|
|
9584
|
+
"Inactive (",
|
|
9585
|
+
inactiveTicks.length,
|
|
9586
|
+
")"
|
|
9587
|
+
] }),
|
|
9588
|
+
/* @__PURE__ */ jsx(Stack, { gap: "sm", children: inactiveTicks.map((tick) => /* @__PURE__ */ jsx(TickCard, { tick, active: false }, tick.id)) })
|
|
9589
|
+
] })
|
|
9590
|
+
] });
|
|
9591
|
+
}
|
|
9592
|
+
TicksTab.displayName = "TicksTab";
|
|
9593
|
+
function EntitiesTab({ snapshot }) {
|
|
9594
|
+
if (!snapshot) {
|
|
9595
|
+
return /* @__PURE__ */ jsx(
|
|
9596
|
+
EmptyState,
|
|
9597
|
+
{
|
|
9598
|
+
title: "No entity data",
|
|
9599
|
+
description: "Debug mode may not be enabled",
|
|
9600
|
+
className: "py-8"
|
|
9601
|
+
}
|
|
9602
|
+
);
|
|
9603
|
+
}
|
|
9604
|
+
const singletonEntries = Object.entries(snapshot.singletons);
|
|
9605
|
+
const runtimeEntities = snapshot.runtime;
|
|
9606
|
+
const persistentEntries = Object.entries(snapshot.persistent);
|
|
9607
|
+
if (singletonEntries.length === 0 && runtimeEntities.length === 0 && persistentEntries.length === 0) {
|
|
9608
|
+
return /* @__PURE__ */ jsx(
|
|
9609
|
+
EmptyState,
|
|
9610
|
+
{
|
|
9611
|
+
title: "No entities",
|
|
9612
|
+
description: "Entities will appear when spawned",
|
|
9613
|
+
className: "py-8"
|
|
9614
|
+
}
|
|
9615
|
+
);
|
|
9616
|
+
}
|
|
9617
|
+
const singletonItems = singletonEntries.map(([name, data]) => ({
|
|
9618
|
+
id: `singleton-${name}`,
|
|
9619
|
+
header: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
9620
|
+
/* @__PURE__ */ jsx(Badge, { variant: "primary", size: "sm", children: "Singleton" }),
|
|
9621
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "semibold", className: "text-sky-600 dark:text-sky-400", children: name })
|
|
9622
|
+
] }),
|
|
9623
|
+
content: /* @__PURE__ */ jsx("pre", { className: "text-xs text-gray-600 dark:text-gray-400 bg-gray-50 dark:bg-gray-800 p-2 rounded overflow-auto max-h-40", children: JSON.stringify(data, null, 2) })
|
|
9624
|
+
}));
|
|
9625
|
+
const runtimeItems = runtimeEntities.slice(0, 20).map((entity) => ({
|
|
9626
|
+
id: entity.id,
|
|
9627
|
+
header: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
9628
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "semibold", className: "text-sky-600 dark:text-sky-400", children: entity.type }),
|
|
9629
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "small", className: "text-gray-500", children: [
|
|
9630
|
+
"#",
|
|
9631
|
+
entity.id.slice(0, 8)
|
|
9632
|
+
] })
|
|
9633
|
+
] }),
|
|
9634
|
+
content: /* @__PURE__ */ jsx("pre", { className: "text-xs text-gray-600 dark:text-gray-400 bg-gray-50 dark:bg-gray-800 p-2 rounded overflow-auto max-h-40", children: JSON.stringify(entity.data, null, 2) })
|
|
9635
|
+
}));
|
|
9636
|
+
return /* @__PURE__ */ jsxs("div", { className: "debug-tab debug-tab--entities", children: [
|
|
9637
|
+
singletonItems.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
9638
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "small", weight: "medium", className: "text-gray-500 mb-2", children: [
|
|
9639
|
+
"Singletons (",
|
|
9640
|
+
singletonItems.length,
|
|
9641
|
+
")"
|
|
9642
|
+
] }),
|
|
9643
|
+
/* @__PURE__ */ jsx(Accordion, { items: singletonItems, multiple: true })
|
|
9644
|
+
] }),
|
|
9645
|
+
runtimeItems.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
9646
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "small", weight: "medium", className: "text-gray-500 mb-2", children: [
|
|
9647
|
+
"Runtime (",
|
|
9648
|
+
runtimeEntities.length,
|
|
9649
|
+
")"
|
|
9650
|
+
] }),
|
|
9651
|
+
/* @__PURE__ */ jsx(Accordion, { items: runtimeItems, multiple: true }),
|
|
9652
|
+
runtimeEntities.length > 20 && /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "text-gray-400 text-center mt-2", children: [
|
|
9653
|
+
"+",
|
|
9654
|
+
runtimeEntities.length - 20,
|
|
9655
|
+
" more entities"
|
|
9656
|
+
] })
|
|
9657
|
+
] }),
|
|
9658
|
+
persistentEntries.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
|
|
9659
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "text-gray-500 mb-2", children: "Persistent" }),
|
|
9660
|
+
/* @__PURE__ */ jsx(Stack, { gap: "xs", children: persistentEntries.map(([type, info]) => /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between py-1", children: [
|
|
9661
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", children: type }),
|
|
9662
|
+
/* @__PURE__ */ jsx(Badge, { variant: info.loaded ? "success" : "default", size: "sm", children: info.loaded ? `${info.count} loaded` : "not loaded" })
|
|
9663
|
+
] }, type)) })
|
|
9664
|
+
] })
|
|
9665
|
+
] });
|
|
9666
|
+
}
|
|
9667
|
+
EntitiesTab.displayName = "EntitiesTab";
|
|
9668
|
+
var TYPE_BADGES = {
|
|
9669
|
+
trait: { variant: "primary", icon: "\u{1F504}" },
|
|
9670
|
+
tick: { variant: "warning", icon: "\u23F1\uFE0F" },
|
|
9671
|
+
guard: { variant: "warning", icon: "\u{1F6E1}\uFE0F" },
|
|
9672
|
+
entity: { variant: "info", icon: "\u{1F4E6}" },
|
|
9673
|
+
event: { variant: "success", icon: "\u26A1" },
|
|
9674
|
+
state: { variant: "danger", icon: "\u{1F4CA}" }
|
|
9675
|
+
};
|
|
9676
|
+
function EventFlowTab({ events }) {
|
|
9677
|
+
const [filter, setFilter] = React44.useState("all");
|
|
9678
|
+
const containerRef = React44.useRef(null);
|
|
9679
|
+
const [autoScroll, setAutoScroll] = React44.useState(true);
|
|
9680
|
+
React44.useEffect(() => {
|
|
9681
|
+
if (autoScroll && containerRef.current) {
|
|
9682
|
+
containerRef.current.scrollTop = containerRef.current.scrollHeight;
|
|
9683
|
+
}
|
|
9684
|
+
}, [events.length, autoScroll]);
|
|
9685
|
+
const filteredEvents = React44.useMemo(() => {
|
|
9686
|
+
if (filter === "all") return events;
|
|
9687
|
+
return events.filter((e) => e.type === filter);
|
|
9688
|
+
}, [events, filter]);
|
|
9689
|
+
const formatTime = (timestamp) => {
|
|
9690
|
+
const date = new Date(timestamp);
|
|
9691
|
+
return date.toLocaleTimeString("en-US", {
|
|
9692
|
+
hour12: false,
|
|
9693
|
+
hour: "2-digit",
|
|
9694
|
+
minute: "2-digit",
|
|
9695
|
+
second: "2-digit"
|
|
9696
|
+
}) + "." + String(date.getMilliseconds()).padStart(3, "0");
|
|
9697
|
+
};
|
|
9698
|
+
if (events.length === 0) {
|
|
9699
|
+
return /* @__PURE__ */ jsx(
|
|
9700
|
+
EmptyState,
|
|
9701
|
+
{
|
|
9702
|
+
title: "No events yet",
|
|
9703
|
+
description: "Events will appear as traits, ticks, and other systems execute",
|
|
9704
|
+
className: "py-8"
|
|
9705
|
+
}
|
|
9706
|
+
);
|
|
9707
|
+
}
|
|
9708
|
+
const eventTypes = Object.keys(TYPE_BADGES).filter(
|
|
9709
|
+
(type) => events.some((e) => e.type === type)
|
|
9710
|
+
);
|
|
9711
|
+
return /* @__PURE__ */ jsxs("div", { className: "debug-tab debug-tab--events", children: [
|
|
9712
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-3 flex-wrap", children: [
|
|
9713
|
+
/* @__PURE__ */ jsxs(ButtonGroup, { children: [
|
|
9714
|
+
/* @__PURE__ */ jsxs(
|
|
9715
|
+
Button,
|
|
9716
|
+
{
|
|
9717
|
+
size: "sm",
|
|
9718
|
+
variant: filter === "all" ? "primary" : "secondary",
|
|
9719
|
+
onClick: () => setFilter("all"),
|
|
9720
|
+
children: [
|
|
9721
|
+
"All (",
|
|
9722
|
+
events.length,
|
|
9723
|
+
")"
|
|
9724
|
+
]
|
|
9725
|
+
}
|
|
9726
|
+
),
|
|
9727
|
+
eventTypes.map((type) => {
|
|
9728
|
+
const count = events.filter((e) => e.type === type).length;
|
|
9729
|
+
const { icon } = TYPE_BADGES[type];
|
|
9730
|
+
return /* @__PURE__ */ jsxs(
|
|
9731
|
+
Button,
|
|
9732
|
+
{
|
|
9733
|
+
size: "sm",
|
|
9734
|
+
variant: filter === type ? "primary" : "secondary",
|
|
9735
|
+
onClick: () => setFilter(type),
|
|
9736
|
+
children: [
|
|
9737
|
+
icon,
|
|
9738
|
+
" ",
|
|
9739
|
+
count
|
|
9740
|
+
]
|
|
9741
|
+
},
|
|
9742
|
+
type
|
|
9743
|
+
);
|
|
9744
|
+
})
|
|
9745
|
+
] }),
|
|
9746
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-1 text-xs text-gray-500 ml-auto cursor-pointer", children: [
|
|
9747
|
+
/* @__PURE__ */ jsx(
|
|
9748
|
+
Checkbox,
|
|
9749
|
+
{
|
|
9750
|
+
checked: autoScroll,
|
|
9751
|
+
onChange: (e) => setAutoScroll(e.target.checked)
|
|
9752
|
+
}
|
|
9753
|
+
),
|
|
9754
|
+
"Auto-scroll"
|
|
9755
|
+
] })
|
|
9756
|
+
] }),
|
|
9757
|
+
/* @__PURE__ */ jsx(
|
|
9758
|
+
"div",
|
|
9759
|
+
{
|
|
9760
|
+
ref: containerRef,
|
|
9761
|
+
className: "max-h-64 overflow-y-auto space-y-1 bg-gray-50 dark:bg-gray-800 rounded p-2",
|
|
9762
|
+
children: filteredEvents.slice(-100).map((event) => {
|
|
9763
|
+
const { variant, icon } = TYPE_BADGES[event.type] || { variant: "default", icon: "\u2022" };
|
|
9764
|
+
return /* @__PURE__ */ jsxs(
|
|
9765
|
+
"div",
|
|
9766
|
+
{
|
|
9767
|
+
className: "flex items-start gap-2 text-xs py-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded px-1",
|
|
9768
|
+
children: [
|
|
9769
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-gray-400 font-mono min-w-[65px]", children: formatTime(event.timestamp) }),
|
|
9770
|
+
/* @__PURE__ */ jsx("span", { children: icon }),
|
|
9771
|
+
/* @__PURE__ */ jsx(Badge, { variant, size: "sm", className: "min-w-[60px] justify-center", children: event.source }),
|
|
9772
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-gray-600 dark:text-gray-400", children: event.message })
|
|
9773
|
+
]
|
|
9774
|
+
},
|
|
9775
|
+
event.id
|
|
9776
|
+
);
|
|
9777
|
+
})
|
|
9778
|
+
}
|
|
9779
|
+
)
|
|
9780
|
+
] });
|
|
9781
|
+
}
|
|
9782
|
+
EventFlowTab.displayName = "EventFlowTab";
|
|
9783
|
+
function GuardsPanel({ guards }) {
|
|
9784
|
+
const [filter, setFilter] = React44.useState("all");
|
|
9785
|
+
if (guards.length === 0) {
|
|
9786
|
+
return /* @__PURE__ */ jsx(
|
|
9787
|
+
EmptyState,
|
|
9788
|
+
{
|
|
9789
|
+
title: "No guard evaluations",
|
|
9790
|
+
description: "Guard evaluations will appear when transitions or ticks with guards execute",
|
|
9791
|
+
className: "py-8"
|
|
9792
|
+
}
|
|
9793
|
+
);
|
|
9794
|
+
}
|
|
9795
|
+
const passedCount = guards.filter((g) => g.result).length;
|
|
9796
|
+
const failedCount = guards.length - passedCount;
|
|
9797
|
+
const filteredGuards = React44.useMemo(() => {
|
|
9798
|
+
if (filter === "all") return guards;
|
|
9799
|
+
if (filter === "passed") return guards.filter((g) => g.result);
|
|
9800
|
+
return guards.filter((g) => !g.result);
|
|
9801
|
+
}, [guards, filter]);
|
|
9802
|
+
const formatTime = (timestamp) => {
|
|
9803
|
+
const date = new Date(timestamp);
|
|
9804
|
+
return date.toLocaleTimeString("en-US", {
|
|
9805
|
+
hour12: false,
|
|
9806
|
+
hour: "2-digit",
|
|
9807
|
+
minute: "2-digit",
|
|
9808
|
+
second: "2-digit"
|
|
9809
|
+
});
|
|
9810
|
+
};
|
|
9811
|
+
const accordionItems = filteredGuards.slice(-50).reverse().map((guard) => ({
|
|
9812
|
+
id: guard.id,
|
|
9813
|
+
header: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 w-full", children: [
|
|
9814
|
+
/* @__PURE__ */ jsx(Badge, { variant: guard.result ? "success" : "danger", size: "sm", children: guard.result ? "\u2713" : "\u2717" }),
|
|
9815
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", weight: "semibold", className: "text-amber-600 dark:text-amber-400", children: guard.guardName }),
|
|
9816
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-gray-500", children: guard.context.type === "transition" ? `${guard.context.transitionFrom} \u2192 ${guard.context.transitionTo}` : guard.context.tickName }),
|
|
9817
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-gray-400 ml-auto", children: formatTime(guard.timestamp) })
|
|
9818
|
+
] }),
|
|
9819
|
+
content: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
9820
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
9821
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "text-gray-500", children: "Expression" }),
|
|
9822
|
+
/* @__PURE__ */ jsx("code", { className: "block mt-1 text-xs text-amber-600 dark:text-amber-400 bg-amber-50 dark:bg-amber-900/20 px-2 py-1 rounded", children: guard.expression })
|
|
9823
|
+
] }),
|
|
9824
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
9825
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "text-gray-500", children: "Inputs" }),
|
|
9826
|
+
/* @__PURE__ */ jsx("pre", { className: "mt-1 text-xs text-gray-600 dark:text-gray-400 bg-gray-50 dark:bg-gray-800 p-2 rounded overflow-auto max-h-24", children: JSON.stringify(guard.inputs, null, 2) })
|
|
9827
|
+
] }),
|
|
9828
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
9829
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "text-gray-500", children: "Trait" }),
|
|
9830
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", children: guard.context.traitName })
|
|
9831
|
+
] })
|
|
9832
|
+
] })
|
|
9833
|
+
}));
|
|
9834
|
+
return /* @__PURE__ */ jsxs("div", { className: "debug-tab debug-tab--guards", children: [
|
|
9835
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-3", children: [
|
|
9836
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-3", children: [
|
|
9837
|
+
/* @__PURE__ */ jsxs(Badge, { variant: "success", size: "sm", children: [
|
|
9838
|
+
"\u2713 ",
|
|
9839
|
+
passedCount
|
|
9840
|
+
] }),
|
|
9841
|
+
/* @__PURE__ */ jsxs(Badge, { variant: "danger", size: "sm", children: [
|
|
9842
|
+
"\u2717 ",
|
|
9843
|
+
failedCount
|
|
9844
|
+
] })
|
|
9845
|
+
] }),
|
|
9846
|
+
/* @__PURE__ */ jsxs(ButtonGroup, { children: [
|
|
9847
|
+
/* @__PURE__ */ jsx(Button, { size: "sm", variant: filter === "all" ? "primary" : "secondary", onClick: () => setFilter("all"), children: "All" }),
|
|
9848
|
+
/* @__PURE__ */ jsx(Button, { size: "sm", variant: filter === "passed" ? "primary" : "secondary", onClick: () => setFilter("passed"), children: "Passed" }),
|
|
9849
|
+
/* @__PURE__ */ jsx(Button, { size: "sm", variant: filter === "failed" ? "primary" : "secondary", onClick: () => setFilter("failed"), children: "Failed" })
|
|
9850
|
+
] })
|
|
9851
|
+
] }),
|
|
9852
|
+
/* @__PURE__ */ jsx("div", { className: "max-h-80 overflow-y-auto", children: /* @__PURE__ */ jsx(Accordion, { items: accordionItems }) })
|
|
9853
|
+
] });
|
|
9854
|
+
}
|
|
9855
|
+
GuardsPanel.displayName = "GuardsPanel";
|
|
9856
|
+
var STATUS_CONFIG = {
|
|
9857
|
+
pass: { variant: "success", icon: "\u2713", label: "PASS" },
|
|
9858
|
+
fail: { variant: "danger", icon: "\u2717", label: "FAIL" },
|
|
9859
|
+
warn: { variant: "warning", icon: "!", label: "WARN" },
|
|
9860
|
+
pending: { variant: "default", icon: "?", label: "PENDING" }
|
|
9861
|
+
};
|
|
9862
|
+
function VerificationTab({ checks, summary }) {
|
|
9863
|
+
if (checks.length === 0) {
|
|
9864
|
+
return /* @__PURE__ */ jsx(
|
|
9865
|
+
EmptyState,
|
|
9866
|
+
{
|
|
9867
|
+
title: "No verification checks yet",
|
|
9868
|
+
description: "Checks will appear as the app executes transitions and effects",
|
|
9869
|
+
className: "py-8"
|
|
9870
|
+
}
|
|
9871
|
+
);
|
|
9872
|
+
}
|
|
9873
|
+
const sortOrder = { fail: 0, warn: 1, pending: 2, pass: 3 };
|
|
9874
|
+
const sorted = [...checks].sort(
|
|
9875
|
+
(a, b) => (sortOrder[a.status] ?? 4) - (sortOrder[b.status] ?? 4)
|
|
9876
|
+
);
|
|
9877
|
+
return /* @__PURE__ */ jsxs("div", { className: "debug-tab debug-tab--verification", children: [
|
|
9878
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 mb-3 p-2 bg-gray-50 dark:bg-gray-800 rounded", children: [
|
|
9879
|
+
/* @__PURE__ */ jsxs(Badge, { variant: "success", size: "sm", children: [
|
|
9880
|
+
summary.passed,
|
|
9881
|
+
" passed"
|
|
9882
|
+
] }),
|
|
9883
|
+
summary.failed > 0 && /* @__PURE__ */ jsxs(Badge, { variant: "danger", size: "sm", children: [
|
|
9884
|
+
summary.failed,
|
|
9885
|
+
" failed"
|
|
9886
|
+
] }),
|
|
9887
|
+
summary.warnings > 0 && /* @__PURE__ */ jsxs(Badge, { variant: "warning", size: "sm", children: [
|
|
9888
|
+
summary.warnings,
|
|
9889
|
+
" warnings"
|
|
9890
|
+
] }),
|
|
9891
|
+
summary.pending > 0 && /* @__PURE__ */ jsxs(Badge, { variant: "default", size: "sm", children: [
|
|
9892
|
+
summary.pending,
|
|
9893
|
+
" pending"
|
|
9894
|
+
] }),
|
|
9895
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "small", className: "text-gray-500 ml-auto", children: [
|
|
9896
|
+
summary.totalChecks,
|
|
9897
|
+
" total checks"
|
|
9898
|
+
] })
|
|
9899
|
+
] }),
|
|
9900
|
+
/* @__PURE__ */ jsx("div", { className: "max-h-64 overflow-y-auto space-y-1", children: /* @__PURE__ */ jsx(Stack, { gap: "xs", children: sorted.map((check) => {
|
|
9901
|
+
const config = STATUS_CONFIG[check.status] || STATUS_CONFIG.pending;
|
|
9902
|
+
return /* @__PURE__ */ jsxs(
|
|
9903
|
+
"div",
|
|
9904
|
+
{
|
|
9905
|
+
className: "flex items-start gap-2 p-2 rounded hover:bg-gray-50 dark:hover:bg-gray-800",
|
|
9906
|
+
children: [
|
|
9907
|
+
/* @__PURE__ */ jsx(Badge, { variant: config.variant, size: "sm", className: "min-w-[20px] justify-center mt-0.5", children: config.icon }),
|
|
9908
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
9909
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", className: "break-words", children: check.label }),
|
|
9910
|
+
check.details && /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-gray-500 break-words", children: check.details })
|
|
9911
|
+
] }),
|
|
9912
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-gray-400 font-mono text-[10px] shrink-0", children: new Date(check.updatedAt).toLocaleTimeString("en-US", {
|
|
9913
|
+
hour12: false,
|
|
9914
|
+
hour: "2-digit",
|
|
9915
|
+
minute: "2-digit",
|
|
9916
|
+
second: "2-digit"
|
|
9917
|
+
}) })
|
|
9918
|
+
]
|
|
9919
|
+
},
|
|
9920
|
+
check.id
|
|
9921
|
+
);
|
|
9922
|
+
}) }) })
|
|
9923
|
+
] });
|
|
9924
|
+
}
|
|
9925
|
+
VerificationTab.displayName = "VerificationTab";
|
|
9926
|
+
var EFFECT_STATUS_VARIANT = {
|
|
9927
|
+
executed: "success",
|
|
9928
|
+
failed: "danger",
|
|
9929
|
+
skipped: "warning"
|
|
9930
|
+
};
|
|
9931
|
+
function EffectBadge({ effect }) {
|
|
9932
|
+
const variant = EFFECT_STATUS_VARIANT[effect.status] || "default";
|
|
9933
|
+
const icon = effect.status === "executed" ? "\u2713" : effect.status === "failed" ? "\u2717" : "-";
|
|
9934
|
+
return /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-[10px] font-mono bg-gray-100 dark:bg-gray-700 rounded px-1.5 py-0.5", children: [
|
|
9935
|
+
/* @__PURE__ */ jsx(Badge, { variant, size: "sm", className: "!text-[9px] !px-1 !py-0", children: icon }),
|
|
9936
|
+
/* @__PURE__ */ jsx("span", { className: "text-gray-600 dark:text-gray-400", children: effect.type }),
|
|
9937
|
+
effect.error && /* @__PURE__ */ jsx("span", { className: "text-red-500 truncate max-w-[120px]", title: effect.error, children: effect.error })
|
|
9938
|
+
] });
|
|
9939
|
+
}
|
|
9940
|
+
function TransitionTimeline({ transitions }) {
|
|
9941
|
+
const containerRef = React44.useRef(null);
|
|
9942
|
+
const [autoScroll, setAutoScroll] = React44.useState(true);
|
|
9943
|
+
const [expandedId, setExpandedId] = React44.useState(null);
|
|
9944
|
+
React44.useEffect(() => {
|
|
9945
|
+
if (autoScroll && containerRef.current) {
|
|
9946
|
+
containerRef.current.scrollTop = containerRef.current.scrollHeight;
|
|
9947
|
+
}
|
|
9948
|
+
}, [transitions.length, autoScroll]);
|
|
9949
|
+
if (transitions.length === 0) {
|
|
9950
|
+
return /* @__PURE__ */ jsx(
|
|
9951
|
+
EmptyState,
|
|
9952
|
+
{
|
|
9953
|
+
title: "No transitions recorded",
|
|
9954
|
+
description: "Transitions will appear as the state machine processes events",
|
|
9955
|
+
className: "py-8"
|
|
9956
|
+
}
|
|
9957
|
+
);
|
|
9958
|
+
}
|
|
9959
|
+
const formatTime = (ts) => {
|
|
9960
|
+
const d = new Date(ts);
|
|
9961
|
+
return d.toLocaleTimeString("en-US", {
|
|
9962
|
+
hour12: false,
|
|
9963
|
+
hour: "2-digit",
|
|
9964
|
+
minute: "2-digit",
|
|
9965
|
+
second: "2-digit"
|
|
9966
|
+
}) + "." + String(d.getMilliseconds()).padStart(3, "0");
|
|
9967
|
+
};
|
|
9968
|
+
const sorted = [...transitions].reverse();
|
|
9969
|
+
return /* @__PURE__ */ jsxs("div", { className: "debug-tab debug-tab--timeline", children: [
|
|
9970
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-2", children: [
|
|
9971
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "small", className: "text-gray-500", children: [
|
|
9972
|
+
transitions.length,
|
|
9973
|
+
" transitions recorded"
|
|
9974
|
+
] }),
|
|
9975
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-1 text-xs text-gray-500 cursor-pointer", children: [
|
|
9976
|
+
/* @__PURE__ */ jsx(
|
|
9977
|
+
Checkbox,
|
|
9978
|
+
{
|
|
9979
|
+
checked: autoScroll,
|
|
9980
|
+
onChange: (e) => setAutoScroll(e.target.checked)
|
|
9981
|
+
}
|
|
9982
|
+
),
|
|
9983
|
+
"Auto-scroll"
|
|
9984
|
+
] })
|
|
9985
|
+
] }),
|
|
9986
|
+
/* @__PURE__ */ jsx(
|
|
9987
|
+
"div",
|
|
9988
|
+
{
|
|
9989
|
+
ref: containerRef,
|
|
9990
|
+
className: "max-h-80 overflow-y-auto space-y-0",
|
|
9991
|
+
children: sorted.map((trace, idx) => {
|
|
9992
|
+
const isExpanded = expandedId === trace.id;
|
|
9993
|
+
const hasFailedEffects = trace.effects.some((e) => e.status === "failed");
|
|
9994
|
+
const allPassed = trace.effects.length > 0 && trace.effects.every((e) => e.status === "executed");
|
|
9995
|
+
return /* @__PURE__ */ jsxs(
|
|
9996
|
+
"div",
|
|
9997
|
+
{
|
|
9998
|
+
className: `
|
|
9999
|
+
relative pl-6 pb-3 border-l-2 cursor-pointer
|
|
10000
|
+
hover:bg-gray-50 dark:hover:bg-gray-800 rounded-r
|
|
10001
|
+
${hasFailedEffects ? "border-red-300 dark:border-red-700" : "border-gray-200 dark:border-gray-700"}
|
|
10002
|
+
`,
|
|
10003
|
+
onClick: () => setExpandedId(isExpanded ? null : trace.id),
|
|
10004
|
+
children: [
|
|
10005
|
+
/* @__PURE__ */ jsx("div", { className: `
|
|
10006
|
+
absolute left-[-5px] top-1 w-2 h-2 rounded-full
|
|
10007
|
+
${hasFailedEffects ? "bg-red-500" : allPassed ? "bg-green-500" : "bg-gray-400"}
|
|
10008
|
+
` }),
|
|
10009
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-xs py-1 px-2", children: [
|
|
10010
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-gray-400 font-mono min-w-[65px]", children: formatTime(trace.timestamp) }),
|
|
10011
|
+
/* @__PURE__ */ jsx(Badge, { variant: "primary", size: "sm", className: "min-w-[60px] justify-center", children: trace.traitName }),
|
|
10012
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "small", className: "font-mono text-gray-600 dark:text-gray-400", children: [
|
|
10013
|
+
trace.from,
|
|
10014
|
+
" ",
|
|
10015
|
+
/* @__PURE__ */ jsx("span", { className: "text-gray-400", children: "\u2192" }),
|
|
10016
|
+
" ",
|
|
10017
|
+
trace.to
|
|
10018
|
+
] }),
|
|
10019
|
+
/* @__PURE__ */ jsx(Badge, { variant: "info", size: "sm", children: trace.event }),
|
|
10020
|
+
trace.guardResult !== void 0 && /* @__PURE__ */ jsxs(
|
|
10021
|
+
Badge,
|
|
10022
|
+
{
|
|
10023
|
+
variant: trace.guardResult ? "success" : "danger",
|
|
10024
|
+
size: "sm",
|
|
10025
|
+
children: [
|
|
10026
|
+
"guard: ",
|
|
10027
|
+
trace.guardResult ? "\u2713" : "\u2717"
|
|
10028
|
+
]
|
|
10029
|
+
}
|
|
10030
|
+
),
|
|
10031
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "small", className: "text-gray-400 ml-auto", children: [
|
|
10032
|
+
trace.effects.length,
|
|
10033
|
+
" effects"
|
|
10034
|
+
] })
|
|
10035
|
+
] }),
|
|
10036
|
+
isExpanded && trace.effects.length > 0 && /* @__PURE__ */ jsx("div", { className: "ml-2 mt-1 mb-2 pl-2 border-l border-gray-200 dark:border-gray-700 space-y-1", children: trace.effects.map((effect, eIdx) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
10037
|
+
/* @__PURE__ */ jsx(EffectBadge, { effect }),
|
|
10038
|
+
effect.args.length > 0 && /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-gray-400 font-mono text-[10px] truncate max-w-[200px]", children: JSON.stringify(effect.args) }),
|
|
10039
|
+
effect.durationMs !== void 0 && /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "text-gray-400 text-[10px]", children: [
|
|
10040
|
+
effect.durationMs,
|
|
10041
|
+
"ms"
|
|
10042
|
+
] })
|
|
10043
|
+
] }, eIdx)) })
|
|
10044
|
+
]
|
|
10045
|
+
},
|
|
10046
|
+
trace.id
|
|
10047
|
+
);
|
|
10048
|
+
})
|
|
10049
|
+
}
|
|
10050
|
+
)
|
|
10051
|
+
] });
|
|
10052
|
+
}
|
|
10053
|
+
TransitionTimeline.displayName = "TransitionTimeline";
|
|
10054
|
+
function StatRow({ label, value, variant }) {
|
|
10055
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between py-1.5 border-b border-gray-100 dark:border-gray-800 last:border-b-0", children: [
|
|
10056
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-gray-500", children: label }),
|
|
10057
|
+
variant ? /* @__PURE__ */ jsx(Badge, { variant, size: "sm", children: String(value) }) : /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "semibold", className: "font-mono", children: String(value) })
|
|
10058
|
+
] });
|
|
10059
|
+
}
|
|
10060
|
+
function ServerBridgeTab({ bridge }) {
|
|
10061
|
+
if (!bridge) {
|
|
10062
|
+
return /* @__PURE__ */ jsx(
|
|
10063
|
+
EmptyState,
|
|
10064
|
+
{
|
|
10065
|
+
title: "No bridge data",
|
|
10066
|
+
description: "The ServerBridge has not been initialized. Bridge health will appear once the runtime connects to the server.",
|
|
10067
|
+
className: "py-8"
|
|
10068
|
+
}
|
|
10069
|
+
);
|
|
10070
|
+
}
|
|
10071
|
+
const formatTime = (ts) => {
|
|
10072
|
+
if (ts === 0) return "Never";
|
|
10073
|
+
const d = new Date(ts);
|
|
10074
|
+
return d.toLocaleTimeString("en-US", {
|
|
10075
|
+
hour12: false,
|
|
10076
|
+
hour: "2-digit",
|
|
10077
|
+
minute: "2-digit",
|
|
10078
|
+
second: "2-digit"
|
|
10079
|
+
});
|
|
10080
|
+
};
|
|
10081
|
+
return /* @__PURE__ */ jsx("div", { className: "debug-tab debug-tab--bridge", children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
10082
|
+
/* @__PURE__ */ jsxs(Card, { className: "p-3", children: [
|
|
10083
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 mb-3", children: [
|
|
10084
|
+
/* @__PURE__ */ jsx("div", { className: `w-3 h-3 rounded-full ${bridge.connected ? "bg-green-500 animate-pulse" : "bg-red-500"}` }),
|
|
10085
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h6", children: bridge.connected ? "Connected" : "Disconnected" })
|
|
10086
|
+
] }),
|
|
10087
|
+
/* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
|
|
10088
|
+
/* @__PURE__ */ jsx(
|
|
10089
|
+
StatRow,
|
|
10090
|
+
{
|
|
10091
|
+
label: "Status",
|
|
10092
|
+
value: bridge.connected ? "Connected" : "Disconnected",
|
|
10093
|
+
variant: bridge.connected ? "success" : "danger"
|
|
10094
|
+
}
|
|
10095
|
+
),
|
|
10096
|
+
/* @__PURE__ */ jsx(
|
|
10097
|
+
StatRow,
|
|
10098
|
+
{
|
|
10099
|
+
label: "Events Forwarded (Client \u2192 Server)",
|
|
10100
|
+
value: bridge.eventsForwarded
|
|
10101
|
+
}
|
|
10102
|
+
),
|
|
10103
|
+
/* @__PURE__ */ jsx(
|
|
10104
|
+
StatRow,
|
|
10105
|
+
{
|
|
10106
|
+
label: "Events Received (Server \u2192 Client)",
|
|
10107
|
+
value: bridge.eventsReceived
|
|
10108
|
+
}
|
|
10109
|
+
),
|
|
10110
|
+
/* @__PURE__ */ jsx(
|
|
10111
|
+
StatRow,
|
|
10112
|
+
{
|
|
10113
|
+
label: "Last Heartbeat",
|
|
10114
|
+
value: formatTime(bridge.lastHeartbeat)
|
|
10115
|
+
}
|
|
10116
|
+
)
|
|
10117
|
+
] })
|
|
10118
|
+
] }),
|
|
10119
|
+
bridge.lastError && /* @__PURE__ */ jsxs(Card, { className: "p-3 border-red-200 dark:border-red-800 bg-red-50 dark:bg-red-950", children: [
|
|
10120
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "semibold", className: "text-red-600 dark:text-red-400 mb-1", children: "Last Error" }),
|
|
10121
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-red-500 font-mono break-all", children: bridge.lastError })
|
|
10122
|
+
] }),
|
|
10123
|
+
bridge.connected && /* @__PURE__ */ jsx("div", { className: "text-center py-2", children: /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "text-gray-400", children: [
|
|
10124
|
+
bridge.eventsForwarded + bridge.eventsReceived,
|
|
10125
|
+
" total events processed"
|
|
10126
|
+
] }) })
|
|
10127
|
+
] }) });
|
|
10128
|
+
}
|
|
10129
|
+
ServerBridgeTab.displayName = "ServerBridgeTab";
|
|
10130
|
+
function extractPayloadFields(schema, eventName) {
|
|
10131
|
+
if (!schema) return [];
|
|
10132
|
+
const orbitals = schema.orbitals;
|
|
10133
|
+
if (!orbitals) return [];
|
|
10134
|
+
for (const orbital of orbitals) {
|
|
10135
|
+
const traits = orbital.traits ?? [];
|
|
10136
|
+
for (const trait of traits) {
|
|
10137
|
+
const sm = trait.stateMachine;
|
|
10138
|
+
if (!sm) continue;
|
|
10139
|
+
const events = sm.events ?? [];
|
|
10140
|
+
for (const evt of events) {
|
|
10141
|
+
if (evt.name !== eventName) continue;
|
|
10142
|
+
const payload = evt.payload ?? [];
|
|
10143
|
+
return payload.map((f) => ({
|
|
10144
|
+
name: f.name,
|
|
10145
|
+
type: f.type ?? "string"
|
|
10146
|
+
}));
|
|
10147
|
+
}
|
|
10148
|
+
}
|
|
10149
|
+
}
|
|
10150
|
+
return [];
|
|
10151
|
+
}
|
|
10152
|
+
function buildAutoPayload(fields) {
|
|
10153
|
+
const payload = {};
|
|
10154
|
+
for (const field of fields) {
|
|
10155
|
+
switch (field.type) {
|
|
10156
|
+
case "number":
|
|
10157
|
+
case "integer":
|
|
10158
|
+
case "float":
|
|
10159
|
+
payload[field.name] = 1;
|
|
10160
|
+
break;
|
|
10161
|
+
case "boolean":
|
|
10162
|
+
payload[field.name] = true;
|
|
10163
|
+
break;
|
|
10164
|
+
default:
|
|
10165
|
+
payload[field.name] = `test-${field.name}`;
|
|
10166
|
+
break;
|
|
10167
|
+
}
|
|
10168
|
+
}
|
|
10169
|
+
return payload;
|
|
10170
|
+
}
|
|
10171
|
+
function getAvailableEvents(traits) {
|
|
10172
|
+
const eventMap = /* @__PURE__ */ new Map();
|
|
10173
|
+
for (const trait of traits) {
|
|
10174
|
+
for (const t of trait.transitions) {
|
|
10175
|
+
if (t.from !== trait.currentState) continue;
|
|
10176
|
+
const existing = eventMap.get(t.event);
|
|
10177
|
+
if (existing) {
|
|
10178
|
+
existing.traits.add(trait.name);
|
|
10179
|
+
existing.transitions.push({ ...t, traitName: trait.name });
|
|
10180
|
+
} else {
|
|
10181
|
+
eventMap.set(t.event, {
|
|
10182
|
+
traits: /* @__PURE__ */ new Set([trait.name]),
|
|
10183
|
+
transitions: [{ ...t, traitName: trait.name }]
|
|
10184
|
+
});
|
|
10185
|
+
}
|
|
10186
|
+
}
|
|
10187
|
+
}
|
|
10188
|
+
return Array.from(eventMap.entries()).map(([event, data]) => ({
|
|
10189
|
+
event,
|
|
10190
|
+
traits: Array.from(data.traits),
|
|
10191
|
+
transitions: data.transitions
|
|
10192
|
+
}));
|
|
10193
|
+
}
|
|
10194
|
+
function getAllEvents(traits) {
|
|
10195
|
+
const all = /* @__PURE__ */ new Set();
|
|
10196
|
+
for (const trait of traits) {
|
|
10197
|
+
for (const t of trait.transitions) {
|
|
10198
|
+
all.add(t.event);
|
|
10199
|
+
}
|
|
10200
|
+
}
|
|
10201
|
+
return all;
|
|
10202
|
+
}
|
|
10203
|
+
function EventDispatcherTab({ traits, schema }) {
|
|
10204
|
+
const eventBus = useEventBus();
|
|
10205
|
+
const [log, setLog] = React44.useState([]);
|
|
10206
|
+
const prevStatesRef = React44.useRef(/* @__PURE__ */ new Map());
|
|
10207
|
+
React44.useEffect(() => {
|
|
10208
|
+
for (const trait of traits) {
|
|
10209
|
+
const prev = prevStatesRef.current.get(trait.id);
|
|
10210
|
+
if (prev && prev !== trait.currentState) {
|
|
10211
|
+
setLog((l) => [
|
|
10212
|
+
{ traitName: trait.name, event: "?", from: prev, to: trait.currentState, timestamp: Date.now() },
|
|
10213
|
+
...l
|
|
10214
|
+
].slice(0, 5));
|
|
10215
|
+
}
|
|
10216
|
+
prevStatesRef.current.set(trait.id, trait.currentState);
|
|
10217
|
+
}
|
|
10218
|
+
}, [traits]);
|
|
10219
|
+
if (traits.length === 0) {
|
|
10220
|
+
return /* @__PURE__ */ jsx(
|
|
10221
|
+
EmptyState,
|
|
10222
|
+
{
|
|
10223
|
+
title: "No active traits",
|
|
10224
|
+
description: "Traits will appear when the state machine initializes",
|
|
10225
|
+
className: "py-8"
|
|
10226
|
+
}
|
|
10227
|
+
);
|
|
10228
|
+
}
|
|
10229
|
+
const availableEvents = getAvailableEvents(traits);
|
|
10230
|
+
const allEvents = getAllEvents(traits);
|
|
10231
|
+
const unavailableEvents = Array.from(allEvents).filter(
|
|
10232
|
+
(e) => !availableEvents.some((ae) => ae.event === e)
|
|
10233
|
+
);
|
|
10234
|
+
const handleFireEvent = (eventName) => {
|
|
10235
|
+
const payloadFields = extractPayloadFields(schema, eventName);
|
|
10236
|
+
const payload = payloadFields.length > 0 ? buildAutoPayload(payloadFields) : {};
|
|
10237
|
+
eventBus.emit(`UI:${eventName}`, payload);
|
|
10238
|
+
};
|
|
10239
|
+
return /* @__PURE__ */ jsxs("div", { className: "debug-tab debug-tab--dispatch", children: [
|
|
10240
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-3", children: [
|
|
10241
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "text-gray-500 mb-1", children: "Active States" }),
|
|
10242
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1", children: traits.map((trait) => /* @__PURE__ */ jsxs(Badge, { variant: "success", size: "sm", children: [
|
|
10243
|
+
trait.name,
|
|
10244
|
+
": ",
|
|
10245
|
+
trait.currentState
|
|
10246
|
+
] }, trait.id)) })
|
|
10247
|
+
] }),
|
|
10248
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-3", children: [
|
|
10249
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "text-gray-500 mb-1", children: "Available Events" }),
|
|
10250
|
+
availableEvents.length === 0 ? /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-gray-400 italic", children: "No transitions from current state" }) : /* @__PURE__ */ jsx(Stack, { gap: "xs", children: availableEvents.map(({ event, transitions }) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
10251
|
+
/* @__PURE__ */ jsx(
|
|
10252
|
+
Button,
|
|
10253
|
+
{
|
|
10254
|
+
onClick: () => handleFireEvent(event),
|
|
10255
|
+
variant: "primary",
|
|
10256
|
+
size: "sm",
|
|
10257
|
+
className: "font-mono text-xs",
|
|
10258
|
+
children: event
|
|
10259
|
+
}
|
|
10260
|
+
),
|
|
10261
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-gray-500", children: transitions.map((t) => `${t.from} -> ${t.to}`).join(", ") }),
|
|
10262
|
+
transitions.some((t) => t.guard) && /* @__PURE__ */ jsx(Badge, { variant: "warning", size: "sm", children: "guarded" })
|
|
10263
|
+
] }, event)) })
|
|
10264
|
+
] }),
|
|
10265
|
+
unavailableEvents.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mb-3", children: [
|
|
10266
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "text-gray-500 mb-1", children: "Other Events (not available from current state)" }),
|
|
10267
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1", children: unavailableEvents.map((event) => /* @__PURE__ */ jsx(Badge, { variant: "default", size: "sm", className: "opacity-50", children: event }, event)) })
|
|
10268
|
+
] }),
|
|
10269
|
+
log.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
|
|
10270
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "text-gray-500 mb-1", children: "Recent Transitions" }),
|
|
10271
|
+
/* @__PURE__ */ jsx(Stack, { gap: "xs", children: log.map((entry, i) => /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "font-mono text-xs", children: [
|
|
10272
|
+
/* @__PURE__ */ jsx("span", { className: "text-purple-400", children: entry.traitName }),
|
|
10273
|
+
" ",
|
|
10274
|
+
/* @__PURE__ */ jsx("span", { className: "text-gray-500", children: entry.from }),
|
|
10275
|
+
" -> ",
|
|
10276
|
+
/* @__PURE__ */ jsx("span", { className: "text-green-400", children: entry.to })
|
|
10277
|
+
] }, i)) })
|
|
10278
|
+
] })
|
|
10279
|
+
] });
|
|
10280
|
+
}
|
|
10281
|
+
EventDispatcherTab.displayName = "EventDispatcherTab";
|
|
10282
|
+
function RuntimeDebugger({
|
|
10283
|
+
position = "bottom-right",
|
|
10284
|
+
defaultCollapsed = true,
|
|
10285
|
+
className,
|
|
10286
|
+
mode = "floating",
|
|
10287
|
+
defaultTab,
|
|
10288
|
+
schema
|
|
10289
|
+
}) {
|
|
10290
|
+
const [isCollapsed, setIsCollapsed] = React44.useState(defaultCollapsed);
|
|
10291
|
+
const [isVisible, setIsVisible] = React44.useState(mode === "inline" || isDebugEnabled());
|
|
10292
|
+
const debugData = useDebugData();
|
|
10293
|
+
React44.useEffect(() => {
|
|
10294
|
+
if (mode === "inline") return;
|
|
10295
|
+
return onDebugToggle((enabled) => {
|
|
10296
|
+
setIsVisible(enabled);
|
|
10297
|
+
if (enabled) {
|
|
10298
|
+
setIsCollapsed(false);
|
|
10299
|
+
}
|
|
10300
|
+
});
|
|
10301
|
+
}, [mode]);
|
|
10302
|
+
React44.useEffect(() => {
|
|
10303
|
+
if (mode === "inline") return;
|
|
10304
|
+
const handleKeyDown = (e) => {
|
|
10305
|
+
if (e.key === "`" && isVisible) {
|
|
10306
|
+
const target = e.target;
|
|
10307
|
+
if (target.tagName === "INPUT" || target.tagName === "TEXTAREA") return;
|
|
10308
|
+
setIsCollapsed((prev) => !prev);
|
|
10309
|
+
}
|
|
10310
|
+
};
|
|
10311
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
10312
|
+
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
10313
|
+
}, [isVisible, mode]);
|
|
10314
|
+
if (!isVisible) {
|
|
10315
|
+
return null;
|
|
10316
|
+
}
|
|
10317
|
+
const positionClasses = {
|
|
10318
|
+
"bottom-right": "bottom-4 right-4",
|
|
10319
|
+
"bottom-left": "bottom-4 left-4",
|
|
10320
|
+
"top-right": "top-4 right-4",
|
|
10321
|
+
"top-left": "top-4 left-4"
|
|
10322
|
+
};
|
|
10323
|
+
const { verification } = debugData;
|
|
10324
|
+
const failedChecks = verification.summary.failed;
|
|
10325
|
+
const tabItems = [
|
|
10326
|
+
{
|
|
10327
|
+
id: "dispatch",
|
|
10328
|
+
label: "Dispatch",
|
|
10329
|
+
badge: debugData.traits.length || void 0,
|
|
10330
|
+
content: /* @__PURE__ */ jsx(EventDispatcherTab, { traits: debugData.traits, schema })
|
|
10331
|
+
},
|
|
10332
|
+
{
|
|
10333
|
+
id: "verify",
|
|
10334
|
+
label: failedChecks > 0 ? "Verify (!)" : "Verify",
|
|
10335
|
+
badge: verification.summary.totalChecks || void 0,
|
|
10336
|
+
content: /* @__PURE__ */ jsx(VerificationTab, { checks: verification.checks, summary: verification.summary })
|
|
10337
|
+
},
|
|
10338
|
+
{
|
|
10339
|
+
id: "timeline",
|
|
10340
|
+
label: "Timeline",
|
|
10341
|
+
badge: verification.transitions.length || void 0,
|
|
10342
|
+
content: /* @__PURE__ */ jsx(TransitionTimeline, { transitions: verification.transitions })
|
|
10343
|
+
},
|
|
10344
|
+
{
|
|
10345
|
+
id: "bridge",
|
|
10346
|
+
label: "Bridge",
|
|
10347
|
+
badge: verification.bridge?.connected ? void 0 : 1,
|
|
10348
|
+
content: /* @__PURE__ */ jsx(ServerBridgeTab, { bridge: verification.bridge })
|
|
10349
|
+
},
|
|
10350
|
+
{
|
|
10351
|
+
id: "traits",
|
|
10352
|
+
label: "Traits",
|
|
10353
|
+
badge: debugData.traits.length || void 0,
|
|
10354
|
+
content: /* @__PURE__ */ jsx(TraitsTab, { traits: debugData.traits })
|
|
10355
|
+
},
|
|
10356
|
+
{
|
|
10357
|
+
id: "ticks",
|
|
10358
|
+
label: "Ticks",
|
|
10359
|
+
badge: debugData.ticks.filter((t) => t.active).length || void 0,
|
|
10360
|
+
content: /* @__PURE__ */ jsx(TicksTab, { ticks: debugData.ticks })
|
|
10361
|
+
},
|
|
10362
|
+
{
|
|
10363
|
+
id: "entities",
|
|
10364
|
+
label: "Entities",
|
|
10365
|
+
badge: debugData.entitySnapshot?.runtime.length || void 0,
|
|
10366
|
+
content: /* @__PURE__ */ jsx(EntitiesTab, { snapshot: debugData.entitySnapshot })
|
|
10367
|
+
},
|
|
10368
|
+
{
|
|
10369
|
+
id: "events",
|
|
10370
|
+
label: "Events",
|
|
10371
|
+
badge: debugData.events.length > 0 ? debugData.events.length : void 0,
|
|
10372
|
+
content: /* @__PURE__ */ jsx(EventFlowTab, { events: debugData.events })
|
|
10373
|
+
},
|
|
10374
|
+
{
|
|
10375
|
+
id: "guards",
|
|
10376
|
+
label: "Guards",
|
|
10377
|
+
badge: debugData.guards.filter((g) => !g.result).length || void 0,
|
|
10378
|
+
content: /* @__PURE__ */ jsx(GuardsPanel, { guards: debugData.guards })
|
|
10379
|
+
}
|
|
10380
|
+
];
|
|
10381
|
+
if (mode === "inline") {
|
|
10382
|
+
return /* @__PURE__ */ jsx(
|
|
10383
|
+
"div",
|
|
10384
|
+
{
|
|
10385
|
+
className: cn(
|
|
10386
|
+
"runtime-debugger",
|
|
10387
|
+
"runtime-debugger--inline",
|
|
10388
|
+
className
|
|
10389
|
+
),
|
|
10390
|
+
"data-testid": "debugger-inline",
|
|
10391
|
+
children: /* @__PURE__ */ jsxs(Card, { className: "runtime-debugger__panel runtime-debugger__panel--inline", children: [
|
|
10392
|
+
/* @__PURE__ */ jsx("div", { className: "runtime-debugger__header", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
10393
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h6", children: "Debugger" }),
|
|
10394
|
+
failedChecks > 0 ? /* @__PURE__ */ jsxs(Badge, { variant: "danger", size: "sm", children: [
|
|
10395
|
+
failedChecks,
|
|
10396
|
+
" failed"
|
|
10397
|
+
] }) : debugData.traits.length > 0 ? /* @__PURE__ */ jsxs(Badge, { variant: "success", size: "sm", children: [
|
|
10398
|
+
debugData.traits.length,
|
|
10399
|
+
" traits"
|
|
10400
|
+
] }) : /* @__PURE__ */ jsx(Badge, { variant: "info", size: "sm", children: "Idle" })
|
|
10401
|
+
] }) }),
|
|
10402
|
+
/* @__PURE__ */ jsx("div", { className: "runtime-debugger__content", children: /* @__PURE__ */ jsx(
|
|
10403
|
+
Tabs,
|
|
10404
|
+
{
|
|
10405
|
+
items: tabItems,
|
|
10406
|
+
defaultActiveTab: defaultTab,
|
|
10407
|
+
variant: "pills",
|
|
10408
|
+
className: "runtime-debugger__tabs"
|
|
10409
|
+
}
|
|
10410
|
+
) })
|
|
10411
|
+
] })
|
|
10412
|
+
}
|
|
10413
|
+
);
|
|
10414
|
+
}
|
|
10415
|
+
return /* @__PURE__ */ jsx(
|
|
10416
|
+
"div",
|
|
10417
|
+
{
|
|
10418
|
+
className: cn(
|
|
10419
|
+
"runtime-debugger",
|
|
10420
|
+
"fixed z-[9999]",
|
|
10421
|
+
positionClasses[position],
|
|
10422
|
+
isCollapsed ? "runtime-debugger--collapsed" : "runtime-debugger--expanded",
|
|
10423
|
+
className
|
|
10424
|
+
),
|
|
10425
|
+
"data-testid": isCollapsed ? "debugger-collapsed" : "debugger-expanded",
|
|
10426
|
+
children: isCollapsed ? /* @__PURE__ */ jsx(
|
|
10427
|
+
Button,
|
|
10428
|
+
{
|
|
10429
|
+
onClick: () => setIsCollapsed(false),
|
|
10430
|
+
variant: "secondary",
|
|
10431
|
+
size: "sm",
|
|
10432
|
+
className: "runtime-debugger__toggle",
|
|
10433
|
+
title: "Open Debugger (`)",
|
|
10434
|
+
children: failedChecks > 0 ? /* @__PURE__ */ jsxs("span", { className: "relative", children: [
|
|
10435
|
+
/* @__PURE__ */ jsx("span", { children: "V" }),
|
|
10436
|
+
/* @__PURE__ */ jsx("span", { className: "absolute -top-1 -right-2 w-2 h-2 bg-red-500 rounded-full" })
|
|
10437
|
+
] }) : /* @__PURE__ */ jsx("span", { children: "V" })
|
|
10438
|
+
}
|
|
10439
|
+
) : /* @__PURE__ */ jsxs(Card, { className: "runtime-debugger__panel", children: [
|
|
10440
|
+
/* @__PURE__ */ jsxs("div", { className: "runtime-debugger__header", children: [
|
|
10441
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
10442
|
+
/* @__PURE__ */ jsx("span", { className: "text-lg", children: "V" }),
|
|
10443
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h6", children: "KFlow Verifier" }),
|
|
10444
|
+
failedChecks > 0 ? /* @__PURE__ */ jsxs(Badge, { variant: "danger", size: "sm", children: [
|
|
10445
|
+
failedChecks,
|
|
10446
|
+
" failed"
|
|
10447
|
+
] }) : verification.summary.totalChecks > 0 ? /* @__PURE__ */ jsx(Badge, { variant: "success", size: "sm", children: "All passing" }) : /* @__PURE__ */ jsx(Badge, { variant: "info", size: "sm", children: "Runtime" })
|
|
10448
|
+
] }),
|
|
10449
|
+
/* @__PURE__ */ jsx(
|
|
10450
|
+
Button,
|
|
10451
|
+
{
|
|
10452
|
+
onClick: () => setIsCollapsed(true),
|
|
10453
|
+
variant: "ghost",
|
|
10454
|
+
size: "sm",
|
|
10455
|
+
title: "Close (`)",
|
|
10456
|
+
children: "x"
|
|
10457
|
+
}
|
|
10458
|
+
)
|
|
10459
|
+
] }),
|
|
10460
|
+
/* @__PURE__ */ jsx("div", { className: "runtime-debugger__content", children: /* @__PURE__ */ jsx(
|
|
10461
|
+
Tabs,
|
|
10462
|
+
{
|
|
10463
|
+
items: tabItems,
|
|
10464
|
+
defaultActiveTab: defaultTab,
|
|
10465
|
+
variant: "pills",
|
|
10466
|
+
className: "runtime-debugger__tabs"
|
|
10467
|
+
}
|
|
10468
|
+
) }),
|
|
10469
|
+
/* @__PURE__ */ jsx("div", { className: "runtime-debugger__footer", children: /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-gray-500", children: "Press ` to toggle | window.__orbitalVerification for automation" }) })
|
|
10470
|
+
] })
|
|
10471
|
+
}
|
|
10472
|
+
);
|
|
10473
|
+
}
|
|
10474
|
+
RuntimeDebugger.displayName = "RuntimeDebugger";
|
|
9404
10475
|
var DashboardLayout = ({
|
|
9405
10476
|
appName = "{{APP_TITLE}}",
|
|
9406
10477
|
logo,
|
|
@@ -10322,4 +11393,4 @@ function WorldMapTemplate({
|
|
|
10322
11393
|
}
|
|
10323
11394
|
WorldMapTemplate.displayName = "WorldMapTemplate";
|
|
10324
11395
|
|
|
10325
|
-
export { AR_BOOK_FIELDS, ActionPalette, ActionTile, AuthLayout, BattleBoard, BattleTemplate, BookChapterView, BookCoverPage, BookNavBar, BookTableOfContents, BookViewer, BuilderBoard, CastleBoard, CastleTemplate, ClassifierBoard, CodeView, CodeViewer, CollapsibleSection, ConfirmDialog, ContentRenderer, CounterTemplate, DashboardGrid, DashboardLayout, DebuggerBoard, DocumentViewer, StateMachineView as DomStateMachineVisualizer, DrawerSlot, EditorCheckbox, EditorSelect, EditorSlider, EditorTextInput, EditorToolbar, EventHandlerBoard, EventLog, FEATURE_TYPES, FormActions, FormLayout, FormSection, GameAudioContext, GameAudioProvider, GameAudioToggle, GameShell, GameTemplate, GenericAppTemplate, GraphCanvas, Header, IDENTITY_BOOK_FIELDS, JazariStateMachine, List, MediaGallery, ModalSlot, Navigation, NegotiatorBoard, NotifyListener, ObjectRulePanel, StateMachineView as OrbitalStateMachineView, OrbitalVisualization, PhysicsManager, RuleEditor, SHEET_COLUMNS, SPRITE_SHEET_LAYOUT, Section, SequenceBar, SequencerBoard, Sidebar, SignaturePad, SimulatorBoard, Split, SplitPane, StateArchitectBoard, StateMachineView, StateNode2 as StateNode, StatusBar, TERRAIN_COLORS, TabbedContainer, Table, TerrainPalette, Timeline, ToastSlot, TraitSlot, TraitStateViewer, TransitionArrow, UncontrolledBattleBoard, VariablePanel, WizardContainer, WorldMapBoard, WorldMapTemplate, applyTemporaryEffect, calculateAttackTargets, calculateDamage, calculateValidMoves, combatAnimations, combatClasses, combatEffects, createInitialGameState, createUnitAnimationState, generateCombatMessage, getCurrentFrame, inferDirection, mapBookData, resolveFieldMap, resolveFrame, resolveSheetDirection, tickAnimationState, transitionAnimation, useBattleState, useGameAudio, useGameAudioContext, usePhysics2D, useSpriteAnimations };
|
|
11396
|
+
export { AR_BOOK_FIELDS, ActionPalette, ActionTile, AuthLayout, BattleBoard, BattleTemplate, BookChapterView, BookCoverPage, BookNavBar, BookTableOfContents, BookViewer, BuilderBoard, CastleBoard, CastleTemplate, ClassifierBoard, CodeView, CodeViewer, CollapsibleSection, ConfirmDialog, ContentRenderer, CounterTemplate, DashboardGrid, DashboardLayout, DebuggerBoard, DocumentViewer, StateMachineView as DomStateMachineVisualizer, DrawerSlot, EditorCheckbox, EditorSelect, EditorSlider, EditorTextInput, EditorToolbar, EventHandlerBoard, EventLog, FEATURE_TYPES, FormActions, FormLayout, FormSection, GameAudioContext, GameAudioProvider, GameAudioToggle, GameShell, GameTemplate, GenericAppTemplate, GraphCanvas, Header, IDENTITY_BOOK_FIELDS, JazariStateMachine, List, MediaGallery, ModalSlot, Navigation, NegotiatorBoard, NotifyListener, ObjectRulePanel, StateMachineView as OrbitalStateMachineView, OrbitalVisualization, PhysicsManager, RuleEditor, RuntimeDebugger, SHEET_COLUMNS, SPRITE_SHEET_LAYOUT, Section, SequenceBar, SequencerBoard, Sidebar, SignaturePad, SimulatorBoard, Split, SplitPane, StateArchitectBoard, StateMachineView, StateNode2 as StateNode, StatusBar, TERRAIN_COLORS, TabbedContainer, Table, TerrainPalette, Timeline, ToastSlot, TraitSlot, TraitStateViewer, TransitionArrow, UncontrolledBattleBoard, VariablePanel, WizardContainer, WorldMapBoard, WorldMapTemplate, applyTemporaryEffect, calculateAttackTargets, calculateDamage, calculateValidMoves, combatAnimations, combatClasses, combatEffects, createInitialGameState, createUnitAnimationState, generateCombatMessage, getCurrentFrame, inferDirection, mapBookData, resolveFieldMap, resolveFrame, resolveSheetDirection, tickAnimationState, transitionAnimation, useBattleState, useGameAudio, useGameAudioContext, usePhysics2D, useSpriteAnimations };
|