@almadar/ui 2.36.0 → 2.38.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/avl/index.js CHANGED
@@ -16,7 +16,7 @@ import { createPortal } from 'react-dom';
16
16
  import * as LucideIcons from 'lucide-react';
17
17
  import { Loader2, ChevronDown, X, ArrowRight, TrendingDown, TrendingUp, Check, Copy, AlertCircle, AlertTriangle, Info, CheckCircle, ChevronLeft, ChevronRight, FileWarning, Upload, Circle, Clock, CheckCircle2, Sun, Moon, ArrowUp, ArrowDown, MoreVertical, Minus, Star, XCircle, Play, RotateCcw, Pause, SkipForward, Eraser, Search, HelpCircle, ChevronUp, ArrowLeft, Plus, Image as Image$1, ZoomIn, Package, Menu as Menu$1, ZoomOut, Filter, FileQuestion, Inbox, FileText, Download, Printer, Bug, Send, MoreHorizontal, Settings, Bell, LogOut, Trash2, Zap, Sword, Move, Heart, Shield, Code, WrapText, Wrench, List, Calendar, Pencil, Eye, User, Tag, DollarSign } from 'lucide-react';
18
18
  import { evaluate, createMinimalContext } from '@almadar/evaluator';
19
- import { getComponentForPattern as getComponentForPattern$1 } from '@almadar/patterns';
19
+ import { getComponentForPattern as getComponentForPattern$1, getPatternDefinition, isEntityAwarePattern } from '@almadar/patterns';
20
20
  import { MapContainer, TileLayer, Marker, Popup, useMap } from 'react-leaflet';
21
21
  import L from 'leaflet';
22
22
  import 'leaflet/dist/leaflet.css';
@@ -25,8 +25,25 @@ import ReactMarkdown from 'react-markdown';
25
25
  import remarkGfm from 'remark-gfm';
26
26
  import remarkMath from 'remark-math';
27
27
  import rehypeKatex from 'rehype-katex';
28
- import SyntaxHighlighter from 'react-syntax-highlighter/dist/esm/prism';
28
+ import SyntaxHighlighter from 'react-syntax-highlighter/dist/esm/prism-light';
29
29
  import dark from 'react-syntax-highlighter/dist/esm/styles/prism/vsc-dark-plus';
30
+ import { orbLanguage, ORB_COLORS } from '@almadar/syntax';
31
+ import langJson from 'react-syntax-highlighter/dist/esm/languages/prism/json';
32
+ import langJavascript from 'react-syntax-highlighter/dist/esm/languages/prism/javascript';
33
+ import langTypescript from 'react-syntax-highlighter/dist/esm/languages/prism/typescript';
34
+ import langJsx from 'react-syntax-highlighter/dist/esm/languages/prism/jsx';
35
+ import langTsx from 'react-syntax-highlighter/dist/esm/languages/prism/tsx';
36
+ import langCss from 'react-syntax-highlighter/dist/esm/languages/prism/css';
37
+ import langMarkdown from 'react-syntax-highlighter/dist/esm/languages/prism/markdown';
38
+ import langBash from 'react-syntax-highlighter/dist/esm/languages/prism/bash';
39
+ import langYaml from 'react-syntax-highlighter/dist/esm/languages/prism/yaml';
40
+ import langRust from 'react-syntax-highlighter/dist/esm/languages/prism/rust';
41
+ import langPython from 'react-syntax-highlighter/dist/esm/languages/prism/python';
42
+ import langSql from 'react-syntax-highlighter/dist/esm/languages/prism/sql';
43
+ import langDiff from 'react-syntax-highlighter/dist/esm/languages/prism/diff';
44
+ import langToml from 'react-syntax-highlighter/dist/esm/languages/prism/toml';
45
+ import langGo from 'react-syntax-highlighter/dist/esm/languages/prism/go';
46
+ import langGraphql from 'react-syntax-highlighter/dist/esm/languages/prism/graphql';
30
47
  import { schemaToIR, getPage, isCircuitEvent } from '@almadar/core';
31
48
  import '@tanstack/react-query';
32
49
  import { StateMachineManager, createContextFromBindings, interpolateValue, EffectExecutor } from '@almadar/runtime';
@@ -21697,6 +21714,51 @@ MarkdownContent.displayName = "MarkdownContent";
21697
21714
  init_Box();
21698
21715
  init_Stack();
21699
21716
  init_useEventBus();
21717
+ SyntaxHighlighter.registerLanguage("json", langJson);
21718
+ SyntaxHighlighter.registerLanguage("javascript", langJavascript);
21719
+ SyntaxHighlighter.registerLanguage("js", langJavascript);
21720
+ SyntaxHighlighter.registerLanguage("typescript", langTypescript);
21721
+ SyntaxHighlighter.registerLanguage("ts", langTypescript);
21722
+ SyntaxHighlighter.registerLanguage("jsx", langJsx);
21723
+ SyntaxHighlighter.registerLanguage("tsx", langTsx);
21724
+ SyntaxHighlighter.registerLanguage("css", langCss);
21725
+ SyntaxHighlighter.registerLanguage("markdown", langMarkdown);
21726
+ SyntaxHighlighter.registerLanguage("md", langMarkdown);
21727
+ SyntaxHighlighter.registerLanguage("bash", langBash);
21728
+ SyntaxHighlighter.registerLanguage("shell", langBash);
21729
+ SyntaxHighlighter.registerLanguage("sh", langBash);
21730
+ SyntaxHighlighter.registerLanguage("yaml", langYaml);
21731
+ SyntaxHighlighter.registerLanguage("yml", langYaml);
21732
+ SyntaxHighlighter.registerLanguage("rust", langRust);
21733
+ SyntaxHighlighter.registerLanguage("python", langPython);
21734
+ SyntaxHighlighter.registerLanguage("py", langPython);
21735
+ SyntaxHighlighter.registerLanguage("sql", langSql);
21736
+ SyntaxHighlighter.registerLanguage("diff", langDiff);
21737
+ SyntaxHighlighter.registerLanguage("toml", langToml);
21738
+ SyntaxHighlighter.registerLanguage("go", langGo);
21739
+ SyntaxHighlighter.registerLanguage("graphql", langGraphql);
21740
+ SyntaxHighlighter.registerLanguage("orb", orbLanguage);
21741
+ var orbStyleOverrides = {
21742
+ "orb-binding": { color: ORB_COLORS.dark.binding, fontWeight: "bold" },
21743
+ "orb-effect": { color: ORB_COLORS.dark.effect, fontWeight: "bold" },
21744
+ "orb-event": { color: ORB_COLORS.dark.event },
21745
+ "orb-slot": { color: ORB_COLORS.dark.uiSlot },
21746
+ "orb-structural": { color: ORB_COLORS.dark.structural },
21747
+ "orb-field-type": { color: ORB_COLORS.dark.fieldType },
21748
+ "orb-persistence": { color: ORB_COLORS.dark.persistence },
21749
+ "orb-pattern": { color: ORB_COLORS.dark.pattern },
21750
+ "orb-behavior": { color: ORB_COLORS.dark.behavior },
21751
+ "orb-unknown-op": { color: ORB_COLORS.dark.error, textDecoration: "wavy underline" },
21752
+ "orb-op-arithmetic": { color: ORB_COLORS.dark.arithmetic, fontWeight: "bold" },
21753
+ "orb-op-comparison": { color: ORB_COLORS.dark.comparison },
21754
+ "orb-op-logic": { color: ORB_COLORS.dark.logic },
21755
+ "orb-op-string": { color: ORB_COLORS.dark.string },
21756
+ "orb-op-collection": { color: ORB_COLORS.dark.collection },
21757
+ "orb-op-time": { color: ORB_COLORS.dark.time },
21758
+ "orb-op-control": { color: ORB_COLORS.dark.control },
21759
+ "orb-op-async": { color: ORB_COLORS.dark.async }
21760
+ };
21761
+ var orbStyle = { ...dark, ...orbStyleOverrides };
21700
21762
  var CodeBlock = React124__default.memo(
21701
21763
  ({
21702
21764
  code: rawCode,
@@ -21707,6 +21769,8 @@ var CodeBlock = React124__default.memo(
21707
21769
  className
21708
21770
  }) => {
21709
21771
  const code = typeof rawCode === "string" ? rawCode : String(rawCode ?? "");
21772
+ const isOrb = language === "orb";
21773
+ const activeStyle = isOrb ? orbStyle : dark;
21710
21774
  const eventBus = useEventBus();
21711
21775
  const { t: _t } = useTranslate();
21712
21776
  const scrollRef = useRef(null);
@@ -21786,7 +21850,7 @@ var CodeBlock = React124__default.memo(
21786
21850
  {
21787
21851
  PreTag: "div",
21788
21852
  language,
21789
- style: dark,
21853
+ style: activeStyle,
21790
21854
  customStyle: {
21791
21855
  backgroundColor: "transparent",
21792
21856
  borderRadius: 0,
@@ -40973,22 +41037,33 @@ function VerifyModePanel({
40973
41037
  }) {
40974
41038
  const scrollRef = React124.useRef(null);
40975
41039
  const prevCountRef = React124.useRef(0);
41040
+ const [walkStep, setWalkStep] = React124.useState(null);
41041
+ React124.useEffect(() => {
41042
+ const interval = setInterval(() => {
41043
+ const w = window;
41044
+ const step = w.__orbitalWalkStep;
41045
+ if (step) setWalkStep(step);
41046
+ }, 300);
41047
+ return () => clearInterval(interval);
41048
+ }, []);
40976
41049
  React124.useEffect(() => {
40977
41050
  if (transitions.length > prevCountRef.current && scrollRef.current) {
40978
41051
  scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
40979
41052
  }
40980
41053
  prevCountRef.current = transitions.length;
40981
41054
  }, [transitions.length]);
40982
- return /* @__PURE__ */ jsxs(
41055
+ const hudBottom = typeof document !== "undefined" ? document.getElementById("slot-hud-bottom") : null;
41056
+ const panel = /* @__PURE__ */ jsxs(
40983
41057
  "div",
40984
41058
  {
40985
41059
  className: cn(
40986
41060
  "runtime-debugger runtime-debugger--verify",
40987
- "fixed bottom-0 left-0 right-0 flex flex-col bg-gray-900 text-white border-t-2 border-cyan-500",
41061
+ "flex flex-col bg-gray-900 text-white border-t-2 border-cyan-500",
41062
+ hudBottom ? "" : "fixed bottom-0 left-0 right-0",
40988
41063
  className
40989
41064
  ),
40990
41065
  "data-testid": "debugger-verify",
40991
- style: { zIndex: 99999, height: "25vh" },
41066
+ style: { height: "25vh", zIndex: hudBottom ? void 0 : 40 },
40992
41067
  children: [
40993
41068
  /* @__PURE__ */ jsxs("div", { className: "px-3 py-1.5 flex items-center gap-3 text-xs font-mono border-b border-gray-700 flex-shrink-0", children: [
40994
41069
  /* @__PURE__ */ jsx(Badge, { variant: failedChecks > 0 ? "danger" : "success", size: "sm", children: failedChecks > 0 ? `${failedChecks} fail` : "OK" }),
@@ -41002,10 +41077,35 @@ function VerifyModePanel({
41002
41077
  ] }),
41003
41078
  traitStates && /* @__PURE__ */ jsx("span", { className: "text-cyan-400 truncate max-w-[400px]", children: traitStates })
41004
41079
  ] }),
41005
- /* @__PURE__ */ jsx("div", { ref: scrollRef, className: "flex-1 overflow-y-auto", children: /* @__PURE__ */ jsx("div", { className: "px-2 py-1", children: transitions.length === 0 ? /* @__PURE__ */ jsx("div", { className: "text-gray-500 text-xs font-mono py-2 text-center", children: "Waiting for transitions..." }) : /* @__PURE__ */ jsx("div", { className: "space-y-0.5", children: transitions.map((trace) => /* @__PURE__ */ jsx(TransitionRow, { trace }, trace.id)) }) }) })
41080
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 flex overflow-hidden", children: [
41081
+ /* @__PURE__ */ jsx("div", { ref: scrollRef, className: "flex-1 overflow-y-auto", children: /* @__PURE__ */ jsx("div", { className: "px-2 py-1", children: transitions.length === 0 ? /* @__PURE__ */ jsx("div", { className: "text-gray-500 text-xs font-mono py-2 text-center", children: "Waiting for transitions..." }) : /* @__PURE__ */ jsx("div", { className: "space-y-0.5", children: transitions.map((trace) => /* @__PURE__ */ jsx(TransitionRow, { trace }, trace.id)) }) }) }),
41082
+ walkStep && /* @__PURE__ */ jsxs("div", { className: "w-56 flex-shrink-0 border-l border-gray-700 px-2 py-1 text-xs font-mono overflow-y-auto", children: [
41083
+ /* @__PURE__ */ jsxs("div", { className: "text-cyan-400 font-bold mb-1", children: [
41084
+ "Walk Step ",
41085
+ walkStep.stepIndex,
41086
+ "/",
41087
+ walkStep.stepTotal
41088
+ ] }),
41089
+ /* @__PURE__ */ jsx("div", { className: "text-gray-300 mb-1", children: walkStep.traitName }),
41090
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 mb-1", children: [
41091
+ /* @__PURE__ */ jsx("span", { className: "text-yellow-300", children: walkStep.from }),
41092
+ /* @__PURE__ */ jsx("span", { className: "text-gray-500", children: "--" }),
41093
+ /* @__PURE__ */ jsx("span", { className: "text-green-300", children: walkStep.event }),
41094
+ /* @__PURE__ */ jsx("span", { className: "text-gray-500", children: "-->" }),
41095
+ /* @__PURE__ */ jsx("span", { className: "text-yellow-300", children: walkStep.to })
41096
+ ] }),
41097
+ walkStep.guardCase && /* @__PURE__ */ jsxs("div", { className: walkStep.guardCase === "pass" ? "text-green-400" : "text-red-400", children: [
41098
+ "guard: ",
41099
+ walkStep.guardCase
41100
+ ] }),
41101
+ walkStep.isRepositioning && /* @__PURE__ */ jsx("div", { className: "text-gray-500 italic", children: "repositioning" }),
41102
+ /* @__PURE__ */ jsx("div", { className: walkStep.accepted ? "text-green-400 mt-1" : "text-red-400 mt-1", children: walkStep.accepted ? "\u2713 accepted" : "\u2717 rejected" })
41103
+ ] })
41104
+ ] })
41006
41105
  ]
41007
41106
  }
41008
41107
  );
41108
+ return hudBottom ? createPortal(panel, hudBottom) : panel;
41009
41109
  }
41010
41110
  function RuntimeDebugger({
41011
41111
  position = "bottom-right",
@@ -46840,20 +46940,14 @@ init_Avl3DStateNode();
46840
46940
  init_Avl3DTransitionArc();
46841
46941
  init_Avl3DExprTree();
46842
46942
 
46843
- // components/organisms/avl/FlowCanvas.tsx
46844
- init_Box();
46845
- init_Typography();
46846
-
46847
- // components/organisms/avl/TransitionPanel.tsx
46943
+ // components/organisms/avl/OrbInspector.tsx
46848
46944
  init_Box();
46849
46945
  init_Typography();
46850
46946
  init_types();
46851
46947
  function formatExpression(expr) {
46852
46948
  if (!expr) return "";
46853
46949
  if (typeof expr === "string") return expr;
46854
- if (Array.isArray(expr)) {
46855
- return `(${expr.map(formatExpression).join(" ")})`;
46856
- }
46950
+ if (Array.isArray(expr)) return `(${expr.map(formatExpression).join(" ")})`;
46857
46951
  return String(expr);
46858
46952
  }
46859
46953
  var KNOWN_EFFECTS = /* @__PURE__ */ new Set([
@@ -46871,153 +46965,255 @@ var KNOWN_EFFECTS = /* @__PURE__ */ new Set([
46871
46965
  "if",
46872
46966
  "log"
46873
46967
  ]);
46874
- function effectSummary(eff) {
46875
- switch (eff.type) {
46876
- case "render-ui":
46877
- return `render-ui ${eff.args[0] ?? "main"}`;
46878
- case "set":
46879
- return `set ${eff.args[0] ?? ""}`;
46880
- case "fetch":
46881
- return `fetch ${eff.args[0] ?? ""}`;
46882
- case "emit":
46883
- return `emit ${eff.args[0] ?? ""}`;
46884
- case "persist":
46885
- return `persist ${eff.args[0] ?? ""} ${eff.args[1] ?? ""}`;
46886
- case "navigate":
46887
- return `navigate ${eff.args[0] ?? ""}`;
46888
- case "call-service":
46889
- return `call-service ${eff.args[0] ?? ""}`;
46890
- case "notify":
46891
- return `notify ${eff.args[0] ?? ""}`;
46892
- default:
46893
- return eff.type;
46894
- }
46968
+ function effectSummary(type) {
46969
+ return type;
46970
+ }
46971
+ var FIELD_TYPE_MAP = {
46972
+ string: "string",
46973
+ number: "number",
46974
+ boolean: "boolean",
46975
+ date: "date",
46976
+ enum: "enum",
46977
+ object: "object",
46978
+ array: "array"
46979
+ };
46980
+ function findEntity(schema, orbitalName) {
46981
+ const orbital = schema.orbitals?.find((o) => o.name === orbitalName);
46982
+ if (!orbital || typeof orbital.entity === "string") return null;
46983
+ const e = orbital.entity;
46984
+ const fields = (e.fields ?? []).map((f3) => ({
46985
+ name: f3.name ?? "",
46986
+ type: f3.type ?? "string",
46987
+ required: f3.required
46988
+ }));
46989
+ return { name: e.name ?? orbitalName, persistence: e.persistence ?? "runtime", fields };
46895
46990
  }
46896
- function TransitionPanel({ node, onClose }) {
46897
- const fromState = node.fromState ?? "unknown";
46898
- const toState = node.toState ?? "unknown";
46899
- const event = node.transitionEvent ?? "INIT";
46900
- const guard = node.guard;
46901
- const effects = node.effectTypes ?? [];
46902
- const entityName = node.entityName ?? "";
46991
+ function findTransition(schema, orbitalName, traitName, event) {
46992
+ const orbital = schema.orbitals?.find((o) => o.name === orbitalName);
46993
+ if (!orbital) return null;
46994
+ const traits2 = orbital.traits ?? [];
46995
+ const trait = traits2.find((t) => typeof t !== "string" && t.name === traitName);
46996
+ if (!trait || typeof trait === "string") return null;
46997
+ const sm = trait.stateMachine;
46998
+ if (!sm) return null;
46999
+ return sm.transitions?.find((t) => t.event === event) ?? null;
47000
+ }
47001
+ function findTraits(schema, orbitalName) {
47002
+ const orbital = schema.orbitals?.find((o) => o.name === orbitalName);
47003
+ if (!orbital) return [];
47004
+ return (orbital.traits ?? []).filter((t) => typeof t !== "string").map((t) => ({
47005
+ name: t.name,
47006
+ stateCount: t.stateMachine?.states?.length ?? 0
47007
+ }));
47008
+ }
47009
+ function OrbInspector({ node, schema, editable = false, onSchemaChange, onClose }) {
47010
+ const { selected: selectedPattern } = useContext(PatternSelectionContext);
47011
+ const [activeTab, setActiveTab] = useState("inspector");
47012
+ const orbitalName = node.orbitalName ?? "";
46903
47013
  const traitName = node.traitName ?? "";
47014
+ const transitionEvent = node.transitionEvent ?? "";
47015
+ const fromState = node.fromState ?? "";
47016
+ const toState = node.toState ?? "";
47017
+ const entityName = node.entityName ?? "";
46904
47018
  const patterns = node.patterns ?? [];
46905
- const effectEntries = effects.map((type) => ({ type, args: [] }));
46906
- const fromRole = getStateRole(fromState);
46907
- const toRole = getStateRole(toState);
46908
- const { selected: selectedPattern } = useContext(PatternSelectionContext);
46909
- return /* @__PURE__ */ jsxs(
46910
- Box,
46911
- {
46912
- className: "flex flex-col bg-card border-l border-border overflow-y-auto",
46913
- style: { width: 340 },
46914
- children: [
46915
- /* @__PURE__ */ jsxs(Box, { className: "flex items-center justify-between px-4 py-3 border-b border-border", children: [
46916
- /* @__PURE__ */ jsx(Typography, { variant: "small", className: "font-semibold", children: selectedPattern ? "Element Inspector" : "Transition Detail" }),
46917
- /* @__PURE__ */ jsx(
46918
- "button",
46919
- {
46920
- onClick: onClose,
46921
- className: "text-muted-foreground hover:text-foreground text-sm cursor-pointer bg-transparent border-none p-1",
46922
- "aria-label": "Close panel",
46923
- children: "\xD7"
46924
- }
46925
- )
47019
+ const effectTypes = node.effectTypes ?? [];
47020
+ const guard = node.guard;
47021
+ const isExpanded = Boolean(traitName);
47022
+ const patternType = selectedPattern?.patternType;
47023
+ const patternDef = useMemo(() => patternType ? getPatternDefinition(patternType) : null, [patternType]);
47024
+ const isEntityPattern = patternType ? isEntityAwarePattern(patternType) : false;
47025
+ const entity = useMemo(() => findEntity(schema, orbitalName), [schema, orbitalName]);
47026
+ const transition = useMemo(() => {
47027
+ if (!traitName || !transitionEvent) return null;
47028
+ return findTransition(schema, orbitalName, traitName, transitionEvent);
47029
+ }, [schema, orbitalName, traitName, transitionEvent]);
47030
+ const traits2 = useMemo(() => findTraits(schema, orbitalName), [schema, orbitalName]);
47031
+ const orbCode = useMemo(() => {
47032
+ const orbital = schema.orbitals?.find((o) => o.name === orbitalName);
47033
+ if (!orbital) return "{}";
47034
+ if (isExpanded && traitName) {
47035
+ const traits3 = orbital.traits ?? [];
47036
+ const trait = traits3.find((t) => typeof t !== "string" && t.name === traitName);
47037
+ if (trait && typeof trait !== "string" && trait.stateMachine) {
47038
+ if (transitionEvent) {
47039
+ const t = trait.stateMachine.transitions?.find((tx) => tx.event === transitionEvent);
47040
+ if (t) return JSON.stringify(t, null, 2);
47041
+ }
47042
+ return JSON.stringify({ name: trait.name, stateMachine: trait.stateMachine }, null, 2);
47043
+ }
47044
+ }
47045
+ return JSON.stringify(orbital, null, 2);
47046
+ }, [schema, orbitalName, traitName, transitionEvent, isExpanded]);
47047
+ const handlePropChange = useCallback((prop, value) => {
47048
+ if (!editable || !onSchemaChange) return;
47049
+ }, [editable, onSchemaChange]);
47050
+ const headerTitle = selectedPattern ? selectedPattern.patternType : isExpanded ? transitionEvent || "Transition" : orbitalName;
47051
+ return /* @__PURE__ */ jsxs(Box, { className: "flex flex-col bg-card border-l border-border h-full", style: { width: 340 }, children: [
47052
+ /* @__PURE__ */ jsxs(Box, { className: "shrink-0 border-b border-border", children: [
47053
+ /* @__PURE__ */ jsxs(Box, { className: "flex items-center justify-between px-4 py-2", children: [
47054
+ /* @__PURE__ */ jsx(Box, { className: "flex items-center gap-2", children: selectedPattern ? /* @__PURE__ */ jsx(
47055
+ Box,
47056
+ {
47057
+ className: "rounded px-2 py-0.5 text-[11px] font-mono font-semibold",
47058
+ style: { backgroundColor: "var(--color-primary)", color: "var(--color-primary-foreground)" },
47059
+ children: headerTitle
47060
+ }
47061
+ ) : /* @__PURE__ */ jsx(Typography, { variant: "small", className: "font-semibold", children: headerTitle }) }),
47062
+ /* @__PURE__ */ jsx(
47063
+ "button",
47064
+ {
47065
+ onClick: onClose,
47066
+ className: "text-muted-foreground hover:text-foreground text-sm cursor-pointer bg-transparent border-none p-1",
47067
+ "aria-label": "Close",
47068
+ children: "\xD7"
47069
+ }
47070
+ )
47071
+ ] }),
47072
+ /* @__PURE__ */ jsxs(Box, { className: "flex px-4 gap-4", children: [
47073
+ /* @__PURE__ */ jsx(
47074
+ "button",
47075
+ {
47076
+ onClick: () => setActiveTab("inspector"),
47077
+ className: `pb-2 text-[12px] font-medium border-b-2 cursor-pointer bg-transparent border-x-0 border-t-0 px-0 ${activeTab === "inspector" ? "border-[var(--color-primary)] text-foreground" : "border-transparent text-muted-foreground hover:text-foreground"}`,
47078
+ children: "Inspector"
47079
+ }
47080
+ ),
47081
+ /* @__PURE__ */ jsx(
47082
+ "button",
47083
+ {
47084
+ onClick: () => setActiveTab("code"),
47085
+ className: `pb-2 text-[12px] font-medium border-b-2 cursor-pointer bg-transparent border-x-0 border-t-0 px-0 ${activeTab === "code" ? "border-[var(--color-primary)] text-foreground" : "border-transparent text-muted-foreground hover:text-foreground"}`,
47086
+ children: "Code"
47087
+ }
47088
+ )
47089
+ ] })
47090
+ ] }),
47091
+ /* @__PURE__ */ jsx(Box, { className: "flex-1 overflow-y-auto", children: activeTab === "code" ? (
47092
+ /* ── Code Tab ── */
47093
+ /* @__PURE__ */ jsx(Box, { className: "p-2", children: /* @__PURE__ */ jsx(
47094
+ CodeBlock,
47095
+ {
47096
+ code: orbCode,
47097
+ language: "orb",
47098
+ showCopyButton: true,
47099
+ showLanguageBadge: true,
47100
+ maxHeight: "100%"
47101
+ }
47102
+ ) })
47103
+ ) : (
47104
+ /* ── Inspector Tab ── */
47105
+ /* @__PURE__ */ jsxs(Fragment, { children: [
47106
+ selectedPattern && patternDef?.propsSchema && /* @__PURE__ */ jsxs(Box, { className: "px-4 py-3 border-b border-border/40", children: [
47107
+ /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-muted-foreground text-[10px] uppercase tracking-wider mb-2", children: "Props" }),
47108
+ /* @__PURE__ */ jsx(Box, { className: "flex flex-col gap-1.5", children: Object.entries(patternDef.propsSchema).slice(0, 8).map(([propName, propSchema]) => {
47109
+ const ps = propSchema;
47110
+ return /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-2", children: [
47111
+ /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-muted-foreground text-[11px] w-20 shrink-0 font-mono", children: propName }),
47112
+ editable ? /* @__PURE__ */ jsx(
47113
+ Input,
47114
+ {
47115
+ placeholder: ps.types?.join(" | ") ?? "string",
47116
+ className: "flex-1 text-[11px] h-6",
47117
+ onChange: (e) => handlePropChange(propName, e.target.value)
47118
+ }
47119
+ ) : /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "text-[11px] text-muted-foreground", children: [
47120
+ ps.types?.join(" | ") ?? "string",
47121
+ ps.required ? " *" : ""
47122
+ ] })
47123
+ ] }, propName);
47124
+ }) })
46926
47125
  ] }),
46927
- selectedPattern && /* @__PURE__ */ jsxs(Box, { className: "px-4 py-3 border-b border-border bg-primary/5", children: [
46928
- /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-muted-foreground text-[10px] uppercase tracking-wider mb-2", children: "Selected Element" }),
47126
+ (selectedPattern && isEntityPattern || !selectedPattern && !isExpanded) && entity && /* @__PURE__ */ jsxs(Box, { className: "px-4 py-3 border-b border-border/40", children: [
47127
+ /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-muted-foreground text-[10px] uppercase tracking-wider mb-2", children: "Entity" }),
46929
47128
  /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-2 mb-2", children: [
46930
- /* @__PURE__ */ jsx(
46931
- Box,
46932
- {
46933
- className: "rounded px-2 py-0.5 text-[11px] font-mono font-semibold",
46934
- style: {
46935
- backgroundColor: "var(--color-primary)",
46936
- color: "var(--color-primary-foreground)"
46937
- },
46938
- children: selectedPattern.patternType
46939
- }
46940
- ),
46941
- selectedPattern.patternId && /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "text-muted-foreground text-[10px] font-mono", children: [
46942
- "#",
46943
- selectedPattern.patternId
46944
- ] })
47129
+ /* @__PURE__ */ jsx("svg", { width: 14, height: 14, children: /* @__PURE__ */ jsx("circle", { cx: 7, cy: 7, r: 5, fill: "var(--color-primary)" }) }),
47130
+ /* @__PURE__ */ jsx(Typography, { variant: "small", className: "font-semibold text-[12px]", children: entity.name }),
47131
+ /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-muted-foreground text-[10px]", children: entity.persistence })
46945
47132
  ] }),
46946
- selectedPattern.sourceTrait && /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "text-muted-foreground text-[10px]", children: [
46947
- "from trait: ",
46948
- selectedPattern.sourceTrait
46949
- ] })
47133
+ /* @__PURE__ */ jsx(Box, { className: "flex flex-col gap-1", children: entity.fields.map((f3) => /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-2", children: [
47134
+ /* @__PURE__ */ jsx("svg", { width: 12, height: 12, children: /* @__PURE__ */ jsx(AvlFieldType, { x: 6, y: 6, kind: FIELD_TYPE_MAP[f3.type] ?? "string", size: 4 }) }),
47135
+ /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-[11px] font-mono flex-1", children: f3.name }),
47136
+ /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-muted-foreground text-[10px]", children: f3.type }),
47137
+ f3.required && /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-primary text-[9px]", children: "req" })
47138
+ ] }, f3.name)) })
47139
+ ] }),
47140
+ !selectedPattern && !isExpanded && traits2.length > 0 && /* @__PURE__ */ jsxs(Box, { className: "px-4 py-3 border-b border-border/40", children: [
47141
+ /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-muted-foreground text-[10px] uppercase tracking-wider mb-2", children: "Traits" }),
47142
+ /* @__PURE__ */ jsx(Box, { className: "flex flex-col gap-1", children: traits2.map((t) => /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-2", children: [
47143
+ /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-[11px] font-semibold", children: t.name }),
47144
+ /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "text-muted-foreground text-[10px]", children: [
47145
+ t.stateCount,
47146
+ " states"
47147
+ ] })
47148
+ ] }, t.name)) })
46950
47149
  ] }),
46951
- /* @__PURE__ */ jsxs(Box, { className: "px-4 py-3 border-b border-border/40", children: [
46952
- /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-muted-foreground text-[10px] uppercase tracking-wider mb-2", children: "State Transition" }),
46953
- /* @__PURE__ */ jsxs("svg", { width: "100%", height: 50, viewBox: "0 0 300 50", children: [
46954
- /* @__PURE__ */ jsx(AvlState, { x: 10, y: 10, name: fromState, role: fromRole, width: 100, height: 28 }),
46955
- /* @__PURE__ */ jsx("line", { x1: 118, y1: 24, x2: 170, y2: 24, stroke: "#1E293B", strokeWidth: 2, markerEnd: "url(#arrow-head)" }),
46956
- /* @__PURE__ */ jsx(AvlState, { x: 178, y: 10, name: toState, role: toRole, width: 100, height: 28 }),
46957
- /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx("marker", { id: "arrow-head", markerWidth: 8, markerHeight: 6, refX: 8, refY: 3, orient: "auto", children: /* @__PURE__ */ jsx("path", { d: "M0,0 L8,3 L0,6 Z", fill: "#1E293B" }) }) })
47150
+ isExpanded && fromState && toState && /* @__PURE__ */ jsxs(Box, { className: "px-4 py-3 border-b border-border/40", children: [
47151
+ /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-muted-foreground text-[10px] uppercase tracking-wider mb-2", children: "Transition" }),
47152
+ /* @__PURE__ */ jsxs("svg", { width: "100%", height: 44, viewBox: "0 0 280 44", children: [
47153
+ /* @__PURE__ */ jsx(AvlState, { x: 8, y: 8, name: fromState, role: getStateRole(fromState), width: 90, height: 26 }),
47154
+ /* @__PURE__ */ jsx("line", { x1: 104, y1: 21, x2: 158, y2: 21, stroke: "#1E293B", strokeWidth: 2, markerEnd: "url(#orb-arrow)" }),
47155
+ /* @__PURE__ */ jsx(AvlState, { x: 164, y: 8, name: toState, role: getStateRole(toState), width: 90, height: 26 }),
47156
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx("marker", { id: "orb-arrow", markerWidth: 8, markerHeight: 6, refX: 8, refY: 3, orient: "auto", children: /* @__PURE__ */ jsx("path", { d: "M0,0 L8,3 L0,6 Z", fill: "#1E293B" }) }) })
46958
47157
  ] }),
46959
- traitName && /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "text-muted-foreground text-[11px] mt-1", children: [
46960
- "Trait: ",
47158
+ traitName && /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "text-muted-foreground text-[11px]", children: [
46961
47159
  traitName,
46962
- " ",
46963
- entityName ? `on ${entityName}` : ""
47160
+ entityName ? ` on ${entityName}` : ""
46964
47161
  ] })
46965
47162
  ] }),
46966
- /* @__PURE__ */ jsxs(Box, { className: "px-4 py-3 border-b border-border/40", children: [
46967
- /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-muted-foreground text-[10px] uppercase tracking-wider mb-2", children: "Trigger" }),
46968
- /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-2", children: [
46969
- /* @__PURE__ */ jsx("svg", { width: 20, height: 20, children: /* @__PURE__ */ jsx(AvlEvent, { x: 10, y: 10, size: 16 }) }),
46970
- /* @__PURE__ */ jsx(Typography, { variant: "small", className: "font-semibold", children: event })
46971
- ] })
46972
- ] }),
46973
- guard && /* @__PURE__ */ jsxs(Box, { className: "px-4 py-3 border-b border-border/40", children: [
46974
- /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-muted-foreground text-[10px] uppercase tracking-wider mb-2", children: "Guard" }),
46975
- /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-2", children: [
46976
- /* @__PURE__ */ jsx("svg", { width: 20, height: 20, children: /* @__PURE__ */ jsx(AvlGuard, { x: 10, y: 10, size: 16 }) }),
46977
- /* @__PURE__ */ jsx(Typography, { variant: "small", className: "font-mono text-[11px]", children: formatExpression(guard) })
46978
- ] })
46979
- ] }),
46980
- /* @__PURE__ */ jsxs(Box, { className: "px-4 py-3 border-b border-border/40", children: [
47163
+ isExpanded && transitionEvent && /* @__PURE__ */ jsx(Box, { className: "px-4 py-2 border-b border-border/40", children: /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-2", children: [
47164
+ /* @__PURE__ */ jsx("svg", { width: 16, height: 16, children: /* @__PURE__ */ jsx(AvlEvent, { x: 8, y: 8, size: 12 }) }),
47165
+ /* @__PURE__ */ jsx(Typography, { variant: "small", className: "font-semibold text-[12px]", children: transitionEvent })
47166
+ ] }) }),
47167
+ (transition?.guard ?? guard) && /* @__PURE__ */ jsx(Box, { className: "px-4 py-2 border-b border-border/40", children: /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-2", children: [
47168
+ /* @__PURE__ */ jsx("svg", { width: 16, height: 16, children: /* @__PURE__ */ jsx(AvlGuard, { x: 8, y: 8, size: 12 }) }),
47169
+ editable ? /* @__PURE__ */ jsx(
47170
+ Input,
47171
+ {
47172
+ defaultValue: formatExpression(transition?.guard ?? guard),
47173
+ className: "flex-1 text-[11px] font-mono h-6"
47174
+ }
47175
+ ) : /* @__PURE__ */ jsx(Typography, { variant: "small", className: "font-mono text-[11px] text-muted-foreground", children: formatExpression(transition?.guard ?? guard) })
47176
+ ] }) }),
47177
+ effectTypes.length > 0 && /* @__PURE__ */ jsxs(Box, { className: "px-4 py-3 border-b border-border/40", children: [
46981
47178
  /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "text-muted-foreground text-[10px] uppercase tracking-wider mb-2", children: [
46982
47179
  "Effects (",
46983
- effectEntries.length,
47180
+ effectTypes.length,
46984
47181
  ")"
46985
47182
  ] }),
46986
- /* @__PURE__ */ jsx(Box, { className: "flex flex-col gap-2", children: effectEntries.map((eff, i) => {
46987
- const isKnown = KNOWN_EFFECTS.has(eff.type);
46988
- const category = EFFECT_TYPE_TO_CATEGORY[eff.type];
47183
+ /* @__PURE__ */ jsx(Box, { className: "flex flex-col gap-1.5", children: effectTypes.map((type, i) => {
47184
+ const isKnown = KNOWN_EFFECTS.has(type);
47185
+ const category = EFFECT_TYPE_TO_CATEGORY[type];
46989
47186
  const catColor = category ? EFFECT_CATEGORY_COLORS[category] : void 0;
46990
47187
  return /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-2", children: [
46991
47188
  /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "text-muted-foreground text-[11px] w-4 text-right shrink-0", children: [
46992
47189
  i + 1,
46993
47190
  "."
46994
47191
  ] }),
46995
- isKnown ? /* @__PURE__ */ jsx("svg", { width: 18, height: 18, children: /* @__PURE__ */ jsx(AvlEffect, { x: 9, y: 9, effectType: eff.type, size: 7, showBackground: true }) }) : /* @__PURE__ */ jsx(Box, { className: "w-[18px] h-[18px] rounded-full bg-muted/30" }),
46996
- /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-[12px]", style: { color: catColor?.color }, children: effectSummary(eff) })
47192
+ isKnown && /* @__PURE__ */ jsx("svg", { width: 16, height: 16, children: /* @__PURE__ */ jsx(AvlEffect, { x: 8, y: 8, effectType: type, size: 6, showBackground: true }) }),
47193
+ /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-[11px]", style: { color: catColor?.color }, children: effectSummary(type) })
46997
47194
  ] }, i);
46998
47195
  }) })
46999
47196
  ] }),
47000
- patterns.length > 0 && /* @__PURE__ */ jsxs(Box, { className: "px-4 py-3", children: [
47001
- /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-muted-foreground text-[10px] uppercase tracking-wider mb-2", children: "render-ui source" }),
47197
+ patterns.length > 0 && !selectedPattern && /* @__PURE__ */ jsxs(Box, { className: "px-4 py-3", children: [
47198
+ /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-muted-foreground text-[10px] uppercase tracking-wider mb-2", children: "render-ui" }),
47002
47199
  /* @__PURE__ */ jsx(Box, { className: "bg-muted/20 rounded-md p-3 font-mono text-[11px] leading-relaxed overflow-x-auto", children: patterns.map((entry, i) => /* @__PURE__ */ jsxs(Box, { children: [
47003
47200
  /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "text-muted-foreground text-[10px]", children: [
47004
47201
  "slot: ",
47005
47202
  entry.slot
47006
47203
  ] }),
47007
- /* @__PURE__ */ jsx(PatternTree, { config: entry.pattern, depth: 0 })
47204
+ /* @__PURE__ */ jsx(OrbPatternTree, { config: entry.pattern, depth: 0 })
47008
47205
  ] }, i)) })
47009
47206
  ] })
47010
- ]
47011
- }
47012
- );
47207
+ ] })
47208
+ ) })
47209
+ ] });
47013
47210
  }
47014
- function PatternTree({ config, depth }) {
47211
+ function OrbPatternTree({ config, depth }) {
47015
47212
  if (!config || typeof config !== "object") return null;
47016
47213
  const { type, children, ...props } = config;
47017
47214
  if (typeof type !== "string") return null;
47018
- const indent = depth * 12;
47019
47215
  const propEntries = Object.entries(props).filter(([k]) => k !== "type");
47020
- return /* @__PURE__ */ jsxs(Box, { style: { paddingLeft: indent }, children: [
47216
+ return /* @__PURE__ */ jsxs(Box, { style: { paddingLeft: depth * 12 }, children: [
47021
47217
  /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-primary font-semibold text-[11px]", children: type }),
47022
47218
  propEntries.slice(0, 5).map(([key, val]) => {
47023
47219
  const display = typeof val === "string" ? val.startsWith("@") ? /* @__PURE__ */ jsx("span", { className: "text-purple-500", children: val }) : `"${val}"` : Array.isArray(val) && typeof val[0] === "string" && val[0].includes("/") ? /* @__PURE__ */ jsxs("span", { className: "text-amber-600", children: [
@@ -47033,10 +47229,14 @@ function PatternTree({ config, depth }) {
47033
47229
  /* @__PURE__ */ jsx("span", { children: display })
47034
47230
  ] }, key);
47035
47231
  }),
47036
- Array.isArray(children) && children.map((child, i) => /* @__PURE__ */ jsx(PatternTree, { config: child, depth: depth + 1 }, i))
47232
+ Array.isArray(children) && children.map((child, i) => /* @__PURE__ */ jsx(OrbPatternTree, { config: child, depth: depth + 1 }, i))
47037
47233
  ] });
47038
47234
  }
47039
- TransitionPanel.displayName = "TransitionPanel";
47235
+ OrbInspector.displayName = "OrbInspector";
47236
+
47237
+ // components/organisms/avl/FlowCanvas.tsx
47238
+ init_Box();
47239
+ init_Typography();
47040
47240
  var NODE_TYPES = {
47041
47241
  preview: OrbPreviewNode
47042
47242
  };
@@ -47054,7 +47254,9 @@ function FlowCanvasInner({
47054
47254
  height = 500,
47055
47255
  onNodeClick,
47056
47256
  onLevelChange,
47057
- initialOrbital
47257
+ initialOrbital,
47258
+ editable,
47259
+ onSchemaChange
47058
47260
  }) {
47059
47261
  const parsedSchema = useMemo(() => {
47060
47262
  if (typeof schemaProp === "string") return JSON.parse(schemaProp);
@@ -47251,7 +47453,16 @@ function FlowCanvasInner({
47251
47453
  }
47252
47454
  )
47253
47455
  ] }),
47254
- selectedNode && /* @__PURE__ */ jsx(TransitionPanel, { node: selectedNode, onClose: handleClosePanel })
47456
+ selectedNode && /* @__PURE__ */ jsx(
47457
+ OrbInspector,
47458
+ {
47459
+ node: selectedNode,
47460
+ schema: parsedSchema,
47461
+ editable,
47462
+ onSchemaChange,
47463
+ onClose: handleClosePanel
47464
+ }
47465
+ )
47255
47466
  ]
47256
47467
  }
47257
47468
  ) }) });
@@ -47788,4 +47999,4 @@ AvlClickTarget.displayName = "AvlClickTarget";
47788
47999
  init_avl_schema_parser();
47789
48000
  init_avl_zoom_state();
47790
48001
 
47791
- export { AVL_FIELD_TYPE_SHAPES, AVL_OPERATOR_COLORS, AvlApplication, AvlBackwardEdge, AvlBehaviorGlyph, AvlBinding, AvlBindingEdge, AvlBindingRef, AvlClickTarget, AvlClosedCircuit, AvlCosmicZoom, AvlEffect, AvlEmitListen, AvlEntity, AvlEvent, AvlEventWireEdge, AvlExprTree, AvlField, AvlFieldType, AvlGuard, AvlLiteral, AvlOperator, AvlOrbital, AvlOrbitalNode, AvlOrbitalUnit, AvlPage, AvlPageEdge, AvlPersistence, AvlSExpr, AvlSlotMap, AvlState, AvlStateMachine, AvlSwimLane, AvlTrait, AvlTraitScene, AvlTransition, AvlTransitionEdge, AvlTransitionLane, AvlTransitionScene, BehaviorView, CONNECTION_COLORS, DOMAIN_COLORS, DetailView, EFFECT_CATEGORY_COLORS, EFFECT_TYPE_TO_CATEGORY, EventFlowEdge, FlowCanvas, MiniStateMachine, ModuleCard, OrbPreviewNode, STATE_COLORS, SystemNode, ZOOM_BAND_THRESHOLDS, ZoomBandContext, ZoomBreadcrumb, ZoomLegend, arcPath, computeTraitLayout, computeZoomBand, curveControlPoint, edgePath, getStateRole, gridPositions, orbitalToExpandedGraph, parseApplicationLevel, parseOrbitalLevel, parseTraitLevel, parseTransitionLevel, radialPositions, ringPositions, schemaToFlowGraph, schemaToOverviewGraph, useZoomBand, zoomProgress };
48002
+ export { AVL_FIELD_TYPE_SHAPES, AVL_OPERATOR_COLORS, AvlApplication, AvlBackwardEdge, AvlBehaviorGlyph, AvlBinding, AvlBindingEdge, AvlBindingRef, AvlClickTarget, AvlClosedCircuit, AvlCosmicZoom, AvlEffect, AvlEmitListen, AvlEntity, AvlEvent, AvlEventWireEdge, AvlExprTree, AvlField, AvlFieldType, AvlGuard, AvlLiteral, AvlOperator, AvlOrbital, AvlOrbitalNode, AvlOrbitalUnit, AvlPage, AvlPageEdge, AvlPersistence, AvlSExpr, AvlSlotMap, AvlState, AvlStateMachine, AvlSwimLane, AvlTrait, AvlTraitScene, AvlTransition, AvlTransitionEdge, AvlTransitionLane, AvlTransitionScene, BehaviorView, CONNECTION_COLORS, DOMAIN_COLORS, DetailView, EFFECT_CATEGORY_COLORS, EFFECT_TYPE_TO_CATEGORY, EventFlowEdge, FlowCanvas, MiniStateMachine, ModuleCard, OrbInspector, OrbPreviewNode, STATE_COLORS, SystemNode, ZOOM_BAND_THRESHOLDS, ZoomBandContext, ZoomBreadcrumb, ZoomLegend, arcPath, computeTraitLayout, computeZoomBand, curveControlPoint, edgePath, getStateRole, gridPositions, orbitalToExpandedGraph, parseApplicationLevel, parseOrbitalLevel, parseTraitLevel, parseTransitionLevel, radialPositions, ringPositions, schemaToFlowGraph, schemaToOverviewGraph, useZoomBand, zoomProgress };