@almadar/ui 2.10.0 → 2.11.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/{chunk-N6DJVKZ6.js → chunk-3E73CE7J.js} +260 -1
- package/dist/{chunk-KPOLHTPA.js → chunk-HQZV4PYL.js} +2 -2
- package/dist/{chunk-7M2KEJTF.js → chunk-QAFNBUDT.js} +1 -1
- package/dist/{chunk-6D5QMEUS.js → chunk-WCTZ7WZX.js} +2 -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 +1091 -20
- package/dist/lib/index.d.ts +175 -313
- package/dist/lib/index.js +2 -263
- package/dist/providers/index.js +3 -3
- package/dist/runtime/index.js +3 -3
- package/package.json +1 -1
- package/dist/cn-BoBXsxuX.d.ts +0 -194
package/dist/components/index.js
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
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-
|
|
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-
|
|
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-QAFNBUDT.js';
|
|
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-QAFNBUDT.js';
|
|
8
8
|
import '../chunk-DKQN5FVU.js';
|
|
9
9
|
import { useTranslate } from '../chunk-WGJIL4YR.js';
|
|
10
10
|
export { EntityDataProvider, I18nProvider, createTranslate, entityDataKeys, parseQueryBinding, useDragReorder, useEntity, useEntityDataAdapter, useEntityDetail, useEntityList, useEntityListSuspense, useEntitySuspense, useInfiniteScroll, useLongPress, usePullToRefresh, useQuerySingleton, useSwipeGesture, useTranslate } from '../chunk-WGJIL4YR.js';
|
|
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-
|
|
15
|
-
export { cn } from '../chunk-
|
|
14
|
+
import { cn, getNestedValue, subscribeToVerification, getSummary, getBridgeHealth, getTransitions, getAllChecks } from '../chunk-WCTZ7WZX.js';
|
|
15
|
+
export { cn } from '../chunk-WCTZ7WZX.js';
|
|
16
16
|
import '../chunk-TSETXL2E.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 };
|