@walkeros/explorer 2.1.0 → 2.1.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.
Files changed (92) hide show
  1. package/AGENT.md +14 -0
  2. package/STYLE.md +6 -0
  3. package/dist/chunk-4AJX6MFW.mjs +573 -0
  4. package/dist/chunk-4AJX6MFW.mjs.map +1 -0
  5. package/dist/components/atoms/button-link.stories.d.ts +1 -3
  6. package/dist/components/atoms/button-link.stories.d.ts.map +1 -1
  7. package/dist/components/atoms/button-link.stories.js +1 -15
  8. package/dist/components/atoms/button-link.stories.js.map +1 -1
  9. package/dist/components/atoms/code.d.ts +29 -1
  10. package/dist/components/atoms/code.d.ts.map +1 -1
  11. package/dist/components/atoms/code.js +76 -8
  12. package/dist/components/atoms/code.js.map +1 -1
  13. package/dist/components/atoms/code.stories.d.ts +0 -7
  14. package/dist/components/atoms/code.stories.d.ts.map +1 -1
  15. package/dist/components/atoms/code.stories.js +0 -34
  16. package/dist/components/atoms/code.stories.js.map +1 -1
  17. package/dist/components/molecules/code-box.d.ts +6 -1
  18. package/dist/components/molecules/code-box.d.ts.map +1 -1
  19. package/dist/components/molecules/code-box.js +45 -3
  20. package/dist/components/molecules/code-box.js.map +1 -1
  21. package/dist/components/molecules/code-box.stories.d.ts +45 -9
  22. package/dist/components/molecules/code-box.stories.d.ts.map +1 -1
  23. package/dist/components/molecules/code-box.stories.js +106 -45
  24. package/dist/components/molecules/code-box.stories.js.map +1 -1
  25. package/dist/components/molecules/code-snippet.stories.d.ts +0 -8
  26. package/dist/components/molecules/code-snippet.stories.d.ts.map +1 -1
  27. package/dist/components/molecules/code-snippet.stories.js +0 -19
  28. package/dist/components/molecules/code-snippet.stories.js.map +1 -1
  29. package/dist/components/molecules/flow-map/FlowMap.stories.d.ts +0 -32
  30. package/dist/components/molecules/flow-map/FlowMap.stories.d.ts.map +1 -1
  31. package/dist/components/molecules/flow-map/FlowMap.stories.js +0 -330
  32. package/dist/components/molecules/flow-map/FlowMap.stories.js.map +1 -1
  33. package/dist/components/molecules/flow-map/FlowMap.transformers.stories.d.ts +0 -16
  34. package/dist/components/molecules/flow-map/FlowMap.transformers.stories.d.ts.map +1 -1
  35. package/dist/components/molecules/flow-map/FlowMap.transformers.stories.js +0 -78
  36. package/dist/components/molecules/flow-map/FlowMap.transformers.stories.js.map +1 -1
  37. package/dist/components/molecules/preview.d.ts.map +1 -1
  38. package/dist/components/molecules/preview.js +32 -22
  39. package/dist/components/molecules/preview.js.map +1 -1
  40. package/dist/index.d.cts +180 -3
  41. package/dist/index.d.ts +9 -0
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +11 -0
  44. package/dist/index.js.map +1 -1
  45. package/dist/index.mjs +1052 -49
  46. package/dist/index.mjs.map +1 -1
  47. package/dist/{monaco-types-OLSF6MIE.mjs → monaco-types-KN2DINPW.mjs} +2 -2
  48. package/dist/styles.css +31 -0
  49. package/dist/types/intellisense.d.ts +31 -0
  50. package/dist/types/intellisense.d.ts.map +1 -0
  51. package/dist/types/intellisense.js +2 -0
  52. package/dist/types/intellisense.js.map +1 -0
  53. package/dist/utils/monaco-intellisense-flow-extractor.d.ts +13 -0
  54. package/dist/utils/monaco-intellisense-flow-extractor.d.ts.map +1 -0
  55. package/dist/utils/monaco-intellisense-flow-extractor.js +161 -0
  56. package/dist/utils/monaco-intellisense-flow-extractor.js.map +1 -0
  57. package/dist/utils/monaco-schema-contract.d.ts +8 -0
  58. package/dist/utils/monaco-schema-contract.d.ts.map +1 -0
  59. package/dist/utils/monaco-schema-contract.js +73 -0
  60. package/dist/utils/monaco-schema-contract.js.map +1 -0
  61. package/dist/utils/monaco-schema-enrichment.d.ts +26 -0
  62. package/dist/utils/monaco-schema-enrichment.d.ts.map +1 -0
  63. package/dist/utils/monaco-schema-enrichment.js +31 -0
  64. package/dist/utils/monaco-schema-enrichment.js.map +1 -0
  65. package/dist/utils/monaco-schema-flow-setup.d.ts +10 -0
  66. package/dist/utils/monaco-schema-flow-setup.d.ts.map +1 -0
  67. package/dist/utils/monaco-schema-flow-setup.js +201 -0
  68. package/dist/utils/monaco-schema-flow-setup.js.map +1 -0
  69. package/dist/utils/monaco-schema-variables.d.ts +4 -0
  70. package/dist/utils/monaco-schema-variables.d.ts.map +1 -0
  71. package/dist/utils/monaco-schema-variables.js +26 -0
  72. package/dist/utils/monaco-schema-variables.js.map +1 -0
  73. package/dist/utils/monaco-walkeros-completions.d.ts +15 -0
  74. package/dist/utils/monaco-walkeros-completions.d.ts.map +1 -0
  75. package/dist/utils/monaco-walkeros-completions.js +65 -0
  76. package/dist/utils/monaco-walkeros-completions.js.map +1 -0
  77. package/dist/utils/monaco-walkeros-decorations.d.ts +29 -0
  78. package/dist/utils/monaco-walkeros-decorations.d.ts.map +1 -0
  79. package/dist/utils/monaco-walkeros-decorations.js +87 -0
  80. package/dist/utils/monaco-walkeros-decorations.js.map +1 -0
  81. package/dist/utils/monaco-walkeros-markers.d.ts +13 -0
  82. package/dist/utils/monaco-walkeros-markers.d.ts.map +1 -0
  83. package/dist/utils/monaco-walkeros-markers.js +69 -0
  84. package/dist/utils/monaco-walkeros-markers.js.map +1 -0
  85. package/dist/utils/monaco-walkeros-providers.d.ts +19 -0
  86. package/dist/utils/monaco-walkeros-providers.d.ts.map +1 -0
  87. package/dist/utils/monaco-walkeros-providers.js +229 -0
  88. package/dist/utils/monaco-walkeros-providers.js.map +1 -0
  89. package/package.json +1 -1
  90. package/dist/chunk-YKT4D7MG.mjs +0 -3087
  91. package/dist/chunk-YKT4D7MG.mjs.map +0 -1
  92. /package/dist/{monaco-types-OLSF6MIE.mjs.map → monaco-types-KN2DINPW.mjs.map} +0 -0
package/dist/index.mjs CHANGED
@@ -5,13 +5,14 @@ import {
5
5
  loadPackageTypes,
6
6
  loadTypeLibraryFromURL,
7
7
  registerWalkerOSTypes
8
- } from "./chunk-YKT4D7MG.mjs";
8
+ } from "./chunk-4AJX6MFW.mjs";
9
9
 
10
10
  // src/components/demos/MappingDemo.tsx
11
11
  import { useState as useState6, useCallback as useCallback5, useEffect as useEffect5 } from "react";
12
12
 
13
13
  // src/components/molecules/code-box.tsx
14
14
  import { useState as useState4, useCallback as useCallback3, useRef as useRef4, useEffect as useEffect3 } from "react";
15
+ import * as monacoNs from "monaco-editor";
15
16
 
16
17
  // src/components/atoms/box.tsx
17
18
  import { useState } from "react";
@@ -646,6 +647,348 @@ function registerDataElbStyles() {
646
647
  document.head.appendChild(style);
647
648
  }
648
649
 
650
+ // src/utils/monaco-walkeros-decorations.ts
651
+ var REFERENCE_PATTERNS = [
652
+ { type: "variable", regex: /\$var\.(\w*)/g, className: "elb-ref-variable" },
653
+ {
654
+ type: "definition",
655
+ regex: /\$def\.(\w*)/g,
656
+ className: "elb-ref-definition"
657
+ },
658
+ { type: "secret", regex: /\$secret\.(\w*)/g, className: "elb-ref-secret" },
659
+ { type: "env", regex: /\$env\.(\w*)/g, className: "elb-ref-env" },
660
+ { type: "code", regex: /\$code:/g, className: "elb-ref-code" }
661
+ ];
662
+ function findWalkerOSReferences(text) {
663
+ const references = [];
664
+ for (const pattern of REFERENCE_PATTERNS) {
665
+ const regex2 = new RegExp(pattern.regex.source, pattern.regex.flags);
666
+ let match;
667
+ while ((match = regex2.exec(text)) !== null) {
668
+ references.push({
669
+ type: pattern.type,
670
+ name: pattern.type === "code" ? "" : match[1] || "",
671
+ startIndex: match.index,
672
+ endIndex: match.index + match[0].length
673
+ });
674
+ }
675
+ }
676
+ return references;
677
+ }
678
+ function applyWalkerOSDecorations(editorInstance) {
679
+ let decorationIds = [];
680
+ function update() {
681
+ const model = editorInstance.getModel();
682
+ if (!model) return;
683
+ const text = model.getValue();
684
+ const references = findWalkerOSReferences(text);
685
+ const decorations = references.map(
686
+ (ref) => {
687
+ const startPos = model.getPositionAt(ref.startIndex);
688
+ const endPos = model.getPositionAt(ref.endIndex);
689
+ const pattern = REFERENCE_PATTERNS.find((p) => p.type === ref.type);
690
+ return {
691
+ range: {
692
+ startLineNumber: startPos.lineNumber,
693
+ startColumn: startPos.column,
694
+ endLineNumber: endPos.lineNumber,
695
+ endColumn: endPos.column
696
+ },
697
+ options: { inlineClassName: pattern.className }
698
+ };
699
+ }
700
+ );
701
+ decorationIds = editorInstance.deltaDecorations(decorationIds, decorations);
702
+ }
703
+ update();
704
+ const disposable = editorInstance.onDidChangeModelContent(() => update());
705
+ return () => {
706
+ disposable.dispose();
707
+ editorInstance.deltaDecorations(decorationIds, []);
708
+ };
709
+ }
710
+ function registerWalkerOSDecorationStyles() {
711
+ if (typeof document === "undefined") return;
712
+ if (document.getElementById("walkeros-ref-styles")) return;
713
+ const style = document.createElement("style");
714
+ style.id = "walkeros-ref-styles";
715
+ style.textContent = `
716
+ .monaco-editor .elb-ref-variable { color: #89ddff !important; font-style: italic; }
717
+ .monaco-editor .elb-ref-definition { color: #c3e88d !important; font-style: italic; }
718
+ .monaco-editor .elb-ref-secret { color: #ffcb6b !important; font-style: italic; }
719
+ .monaco-editor .elb-ref-env { color: #ffcb6b !important; font-style: italic; }
720
+ .monaco-editor .elb-ref-code { color: #c084fc !important; }
721
+ `;
722
+ document.head.appendChild(style);
723
+ }
724
+
725
+ // src/utils/monaco-walkeros-completions.ts
726
+ function getVariableCompletions(variables) {
727
+ if (!variables || Object.keys(variables).length === 0) return [];
728
+ return Object.entries(variables).map(([name, value]) => ({
729
+ label: `$var.${name}`,
730
+ insertText: `$var.${name}`,
731
+ detail: `= ${JSON.stringify(value)}`,
732
+ documentation: `Variable reference. Resolves to \`${JSON.stringify(value)}\` at runtime.`,
733
+ kind: "variable",
734
+ sortText: "0_var_" + name
735
+ }));
736
+ }
737
+ function getDefinitionCompletions(definitions) {
738
+ if (!definitions || Object.keys(definitions).length === 0) return [];
739
+ return Object.keys(definitions).map((name) => ({
740
+ label: `$def.${name}`,
741
+ insertText: `$def.${name}`,
742
+ detail: "(definition)",
743
+ documentation: `Definition reference. Injects the reusable config fragment "${name}" at runtime.`,
744
+ kind: "reference",
745
+ sortText: "0_def_" + name
746
+ }));
747
+ }
748
+ function getSecretCompletions(secrets) {
749
+ if (!secrets || secrets.length === 0) return [];
750
+ return secrets.map((name) => ({
751
+ label: `$secret.${name}`,
752
+ insertText: `$secret.${name}`,
753
+ detail: "(secret)",
754
+ documentation: "Secret reference. Value is securely injected at runtime. Never stored in config.",
755
+ kind: "secret",
756
+ sortText: "0_secret_" + name
757
+ }));
758
+ }
759
+ function getPackageCompletions(packages, platform) {
760
+ if (!packages || packages.length === 0) return [];
761
+ const filtered = platform ? packages.filter((p) => p.platform === platform) : packages;
762
+ return filtered.map((pkg) => ({
763
+ label: pkg.package,
764
+ insertText: pkg.package,
765
+ detail: `${pkg.type} (${pkg.platform})`,
766
+ documentation: `walkerOS ${pkg.type}: ${pkg.shortName}`,
767
+ kind: "module",
768
+ sortText: "1_pkg_" + pkg.shortName
769
+ }));
770
+ }
771
+ function getStepNameCompletions(stepNames, context) {
772
+ if (!stepNames) return [];
773
+ const names = stepNames.transformers || [];
774
+ return names.map((name) => ({
775
+ label: name,
776
+ insertText: name,
777
+ detail: `transformer (${context} chain)`,
778
+ documentation: `Reference to transformer step "${name}" in this flow config.`,
779
+ kind: "reference",
780
+ sortText: "0_step_" + name
781
+ }));
782
+ }
783
+
784
+ // src/utils/monaco-walkeros-providers.ts
785
+ var contextRegistry = /* @__PURE__ */ new Map();
786
+ var disposables = [];
787
+ var registered = false;
788
+ function setIntelliSenseContext(modelPath, context) {
789
+ contextRegistry.set(modelPath, context);
790
+ }
791
+ function removeIntelliSenseContext(modelPath) {
792
+ contextRegistry.delete(modelPath);
793
+ }
794
+ function registerWalkerOSProviders(monaco) {
795
+ if (registered) return;
796
+ registered = true;
797
+ disposables.push(
798
+ monaco.languages.registerCompletionItemProvider("json", {
799
+ triggerCharacters: ['"', ".", "$"],
800
+ provideCompletionItems(model, position) {
801
+ const modelPath = model.uri.toString();
802
+ const context = contextRegistry.get(modelPath);
803
+ if (!context) return { suggestions: [] };
804
+ const lineContent = model.getLineContent(position.lineNumber);
805
+ const textBeforeCursor = lineContent.substring(0, position.column - 1);
806
+ const entries = [];
807
+ if (textBeforeCursor.includes("$var.") || textBeforeCursor.endsWith('"$var')) {
808
+ entries.push(...getVariableCompletions(context.variables));
809
+ } else if (textBeforeCursor.includes("$def.") || textBeforeCursor.endsWith('"$def')) {
810
+ entries.push(...getDefinitionCompletions(context.definitions));
811
+ } else if (textBeforeCursor.includes("$secret.") || textBeforeCursor.endsWith('"$secret')) {
812
+ entries.push(...getSecretCompletions(context.secrets));
813
+ } else if (isInsideKey(model, position, "package")) {
814
+ entries.push(
815
+ ...getPackageCompletions(context.packages, context.platform)
816
+ );
817
+ } else if (isInsideKey(model, position, "next") || isInsideKey(model, position, "before")) {
818
+ const key = isInsideKey(model, position, "next") ? "next" : "before";
819
+ entries.push(...getStepNameCompletions(context.stepNames, key));
820
+ } else if (textBeforeCursor.endsWith('"$') || textBeforeCursor.endsWith('"')) {
821
+ entries.push(...getVariableCompletions(context.variables));
822
+ entries.push(...getDefinitionCompletions(context.definitions));
823
+ entries.push(...getSecretCompletions(context.secrets));
824
+ }
825
+ const refStartMatch = textBeforeCursor.match(
826
+ /\$(?:var|def|secret|env|code)[.:]?\w*$/
827
+ );
828
+ const word = model.getWordUntilPosition(position);
829
+ const startCol = refStartMatch ? position.column - refStartMatch[0].length : word.startColumn;
830
+ const range = {
831
+ startLineNumber: position.lineNumber,
832
+ endLineNumber: position.lineNumber,
833
+ startColumn: startCol,
834
+ endColumn: position.column
835
+ };
836
+ return {
837
+ suggestions: entries.map((entry) => ({
838
+ label: entry.label,
839
+ insertText: entry.insertText,
840
+ detail: entry.detail,
841
+ documentation: entry.documentation,
842
+ kind: mapCompletionKind(monaco, entry.kind),
843
+ sortText: entry.sortText,
844
+ range
845
+ }))
846
+ };
847
+ }
848
+ })
849
+ );
850
+ disposables.push(
851
+ monaco.languages.registerHoverProvider("json", {
852
+ provideHover(model, position) {
853
+ const modelPath = model.uri.toString();
854
+ const context = contextRegistry.get(modelPath);
855
+ if (!context) return null;
856
+ const lineContent = model.getLineContent(position.lineNumber);
857
+ const col = position.column - 1;
858
+ function matchAtCursor(pattern) {
859
+ const regex2 = new RegExp(pattern.source, "g");
860
+ let m;
861
+ while ((m = regex2.exec(lineContent)) !== null) {
862
+ if (col >= m.index && col <= m.index + m[0].length) return m;
863
+ }
864
+ return null;
865
+ }
866
+ const varMatch = matchAtCursor(/\$var\.(\w+)/);
867
+ if (varMatch && context.variables) {
868
+ const name = varMatch[1];
869
+ if (name in context.variables) {
870
+ const value = context.variables[name];
871
+ return {
872
+ range: {
873
+ startLineNumber: position.lineNumber,
874
+ startColumn: varMatch.index + 1,
875
+ endLineNumber: position.lineNumber,
876
+ endColumn: varMatch.index + varMatch[0].length + 1
877
+ },
878
+ contents: [
879
+ {
880
+ value: `**Variable:** \`$var.${name}\`
881
+
882
+ **Value:** \`${JSON.stringify(value)}\`
883
+
884
+ *Resolved at runtime via variable interpolation*`
885
+ }
886
+ ]
887
+ };
888
+ }
889
+ return {
890
+ contents: [
891
+ {
892
+ value: `**Unknown variable** \`$var.${name}\`
893
+
894
+ Defined variables: ${Object.keys(context.variables).join(", ") || "none"}`
895
+ }
896
+ ]
897
+ };
898
+ }
899
+ const defMatch = matchAtCursor(/\$def\.(\w+)/);
900
+ if (defMatch && context.definitions) {
901
+ const name = defMatch[1];
902
+ if (name in context.definitions) {
903
+ return {
904
+ range: {
905
+ startLineNumber: position.lineNumber,
906
+ startColumn: defMatch.index + 1,
907
+ endLineNumber: position.lineNumber,
908
+ endColumn: defMatch.index + defMatch[0].length + 1
909
+ },
910
+ contents: [
911
+ {
912
+ value: `**Definition:** \`$def.${name}\`
913
+
914
+ *Injects reusable config fragment at runtime*`
915
+ }
916
+ ]
917
+ };
918
+ }
919
+ return {
920
+ contents: [
921
+ {
922
+ value: `**Unknown definition** \`$def.${name}\`
923
+
924
+ Defined: ${Object.keys(context.definitions).join(", ") || "none"}`
925
+ }
926
+ ]
927
+ };
928
+ }
929
+ const secretMatch = matchAtCursor(/\$secret\.(\w+)/);
930
+ if (secretMatch) {
931
+ const name = secretMatch[1];
932
+ if (context.secrets?.includes(name)) {
933
+ return {
934
+ range: {
935
+ startLineNumber: position.lineNumber,
936
+ startColumn: secretMatch.index + 1,
937
+ endLineNumber: position.lineNumber,
938
+ endColumn: secretMatch.index + secretMatch[0].length + 1
939
+ },
940
+ contents: [
941
+ {
942
+ value: `**Secret:** \`$secret.${name}\`
943
+
944
+ *Securely injected at runtime. Value not stored in config.*`
945
+ }
946
+ ]
947
+ };
948
+ }
949
+ return {
950
+ contents: [
951
+ {
952
+ value: `**Unknown secret** \`$secret.${name}\`
953
+
954
+ Available secrets: ${context.secrets?.join(", ") || "none"}`
955
+ }
956
+ ]
957
+ };
958
+ }
959
+ return null;
960
+ }
961
+ })
962
+ );
963
+ }
964
+ function disposeWalkerOSProviders() {
965
+ for (const d of disposables) d.dispose();
966
+ disposables.length = 0;
967
+ registered = false;
968
+ contextRegistry.clear();
969
+ }
970
+ function mapCompletionKind(monaco, kind) {
971
+ switch (kind) {
972
+ case "variable":
973
+ return monaco.languages.CompletionItemKind.Variable;
974
+ case "reference":
975
+ return monaco.languages.CompletionItemKind.Reference;
976
+ case "secret":
977
+ return monaco.languages.CompletionItemKind.Constant;
978
+ case "module":
979
+ return monaco.languages.CompletionItemKind.Module;
980
+ case "property":
981
+ return monaco.languages.CompletionItemKind.Property;
982
+ default:
983
+ return monaco.languages.CompletionItemKind.Text;
984
+ }
985
+ }
986
+ function isInsideKey(model, position, key) {
987
+ const lineContent = model.getLineContent(position.lineNumber);
988
+ const pattern = new RegExp(`"${key}"\\s*:\\s*"`);
989
+ return pattern.test(lineContent);
990
+ }
991
+
649
992
  // src/utils/monaco-formatters.ts
650
993
  import * as prettier from "prettier/standalone";
651
994
  import prettierBabel from "prettier/plugins/babel";
@@ -839,19 +1182,19 @@ function useMonacoHeight({
839
1182
  }
840
1183
  }, [enabled, minHeight, maxHeight, onHeightChange]);
841
1184
  const setEditor = useCallback(
842
- (editor) => {
1185
+ (editor2) => {
843
1186
  if (updateTimeoutRef.current) {
844
1187
  clearTimeout(updateTimeoutRef.current);
845
1188
  updateTimeoutRef.current = null;
846
1189
  }
847
- editorRef.current = editor;
848
- if (!enabled || !editor) {
1190
+ editorRef.current = editor2;
1191
+ if (!enabled || !editor2) {
849
1192
  setHeight(defaultHeight);
850
1193
  previousHeightRef.current = defaultHeight;
851
1194
  return;
852
1195
  }
853
1196
  setTimeout(() => updateHeight(), 50);
854
- const disposable = editor.onDidContentSizeChange(() => {
1197
+ const disposable = editor2.onDidContentSizeChange(() => {
855
1198
  if (updateTimeoutRef.current) {
856
1199
  clearTimeout(updateTimeoutRef.current);
857
1200
  }
@@ -860,7 +1203,7 @@ function useMonacoHeight({
860
1203
  updateTimeoutRef.current = null;
861
1204
  }, 150);
862
1205
  });
863
- editor.__heightDisposable = disposable;
1206
+ editor2.__heightDisposable = disposable;
864
1207
  },
865
1208
  [enabled, defaultHeight, updateHeight]
866
1209
  );
@@ -886,11 +1229,14 @@ function Code({
886
1229
  packages,
887
1230
  sticky = true,
888
1231
  ide = false,
889
- jsonSchema
1232
+ jsonSchema,
1233
+ intellisenseContext,
1234
+ validate,
1235
+ onMarkerCounts
890
1236
  }) {
891
1237
  const [isMounted, setIsMounted] = useState3(false);
892
1238
  const [monacoTheme, setMonacoTheme] = useState3("vs-light");
893
- const decorationsCleanupRef = useRef3(null);
1239
+ const decorationsCleanupRef = useRef3([]);
894
1240
  const monacoRef = useRef3(null);
895
1241
  const editorRef = useRef3(null);
896
1242
  const containerRef = useRef3(null);
@@ -965,12 +1311,12 @@ function Code({
965
1311
  };
966
1312
  }, [isMounted, getDataTheme]);
967
1313
  useEffect2(() => {
968
- const editor = editorRef.current;
1314
+ const editor2 = editorRef.current;
969
1315
  const container = containerRef.current;
970
- if (!editor || !container) return;
1316
+ if (!editor2 || !container) return;
971
1317
  const resizeObserver = new ResizeObserver(() => {
972
1318
  requestAnimationFrame(() => {
973
- editor.layout();
1319
+ editor2.layout();
974
1320
  });
975
1321
  });
976
1322
  resizeObserver.observe(container);
@@ -979,7 +1325,13 @@ function Code({
979
1325
  };
980
1326
  }, []);
981
1327
  const modelPathRef = useRef3(null);
982
- if (jsonSchema && !modelPathRef.current) {
1328
+ const intellisenseContextRef = useRef3(intellisenseContext);
1329
+ intellisenseContextRef.current = intellisenseContext;
1330
+ const validateRef = useRef3(validate);
1331
+ validateRef.current = validate;
1332
+ const onMarkerCountsRef = useRef3(onMarkerCounts);
1333
+ onMarkerCountsRef.current = onMarkerCounts;
1334
+ if ((jsonSchema || intellisenseContext) && !modelPathRef.current) {
983
1335
  modelPathRef.current = generateModelPath();
984
1336
  }
985
1337
  useEffect2(() => {
@@ -991,6 +1343,16 @@ function Code({
991
1343
  }
992
1344
  };
993
1345
  }, [jsonSchema]);
1346
+ useEffect2(() => {
1347
+ if (intellisenseContext && modelPathRef.current) {
1348
+ setIntelliSenseContext(modelPathRef.current, intellisenseContext);
1349
+ return () => {
1350
+ if (modelPathRef.current) {
1351
+ removeIntelliSenseContext(modelPathRef.current);
1352
+ }
1353
+ };
1354
+ }
1355
+ }, [intellisenseContext]);
994
1356
  const handleChange = (value) => {
995
1357
  if (onChange && value !== void 0) {
996
1358
  onChange(value);
@@ -1002,7 +1364,7 @@ function Code({
1002
1364
  registerFormatters(monaco);
1003
1365
  if (packages && packages.length > 0) {
1004
1366
  registerWalkerOSTypes(monaco);
1005
- const { loadPackageTypes: loadPackageTypes2 } = await import("./monaco-types-OLSF6MIE.mjs");
1367
+ const { loadPackageTypes: loadPackageTypes2 } = await import("./monaco-types-KN2DINPW.mjs");
1006
1368
  for (const pkg of packages) {
1007
1369
  if (pkg !== "@walkeros/core") {
1008
1370
  await loadPackageTypes2(monaco, { package: pkg }).catch(() => {
@@ -1014,6 +1376,9 @@ function Code({
1014
1376
  const isDark = dataTheme === "dark" || dataTheme === null && window.matchMedia("(prefers-color-scheme: dark)").matches;
1015
1377
  const themeName = isDark ? "elbTheme-dark" : "elbTheme-light";
1016
1378
  monaco.editor.setTheme(themeName);
1379
+ if (language === "json") {
1380
+ registerWalkerOSProviders(monaco);
1381
+ }
1017
1382
  if (beforeMount) {
1018
1383
  beforeMount(monaco);
1019
1384
  }
@@ -1025,11 +1390,54 @@ function Code({
1025
1390
  registerEditor(monacoEditor);
1026
1391
  }
1027
1392
  if (language === "html" && monacoRef.current) {
1028
- decorationsCleanupRef.current = applyDataElbDecorations(
1029
- monacoEditor,
1030
- monacoRef.current
1393
+ decorationsCleanupRef.current.push(
1394
+ applyDataElbDecorations(monacoEditor, monacoRef.current)
1395
+ );
1396
+ }
1397
+ if (language === "json") {
1398
+ registerWalkerOSDecorationStyles();
1399
+ decorationsCleanupRef.current.push(
1400
+ applyWalkerOSDecorations(monacoEditor)
1031
1401
  );
1032
1402
  }
1403
+ if (validateRef.current && monacoRef.current) {
1404
+ const monacoInstance = monacoRef.current;
1405
+ let validateTimer;
1406
+ const runValidation = () => {
1407
+ const model = monacoEditor.getModel();
1408
+ if (!model) return;
1409
+ const text = model.getValue();
1410
+ const fn = validateRef.current;
1411
+ if (!fn) return;
1412
+ const result = fn(text);
1413
+ const allIssues = [...result.errors, ...result.warnings];
1414
+ monacoInstance.editor.setModelMarkers(
1415
+ model,
1416
+ "validate",
1417
+ allIssues.map((issue) => ({
1418
+ severity: issue.severity === "error" ? 8 : 4,
1419
+ message: issue.message,
1420
+ startLineNumber: issue.line,
1421
+ startColumn: issue.column,
1422
+ endLineNumber: issue.endLine ?? issue.line,
1423
+ endColumn: issue.endColumn ?? issue.column + 1
1424
+ }))
1425
+ );
1426
+ onMarkerCountsRef.current?.({
1427
+ errors: result.errors.length,
1428
+ warnings: result.warnings.length
1429
+ });
1430
+ };
1431
+ runValidation();
1432
+ const validateDisposable = monacoEditor.onDidChangeModelContent(() => {
1433
+ clearTimeout(validateTimer);
1434
+ validateTimer = setTimeout(runValidation, 300);
1435
+ });
1436
+ decorationsCleanupRef.current.push(() => {
1437
+ clearTimeout(validateTimer);
1438
+ validateDisposable.dispose();
1439
+ });
1440
+ }
1033
1441
  requestAnimationFrame(() => {
1034
1442
  monacoEditor.layout();
1035
1443
  });
@@ -1039,9 +1447,10 @@ function Code({
1039
1447
  };
1040
1448
  useEffect2(() => {
1041
1449
  return () => {
1042
- if (decorationsCleanupRef.current) {
1043
- decorationsCleanupRef.current();
1450
+ for (const cleanup of decorationsCleanupRef.current) {
1451
+ cleanup();
1044
1452
  }
1453
+ decorationsCleanupRef.current = [];
1045
1454
  };
1046
1455
  }, []);
1047
1456
  const monacoHeight = autoHeight || gridContext?.enabled ? `${calculatedHeight}px` : "100%";
@@ -1081,7 +1490,7 @@ function Code({
1081
1490
  overviewRulerLanes: 0,
1082
1491
  renderLineHighlight: "none",
1083
1492
  renderValidationDecorations: ide || jsonSchema ? "editable" : "off",
1084
- hover: { enabled: ide || !!jsonSchema },
1493
+ hover: { enabled: ide || !!jsonSchema || !!intellisenseContext },
1085
1494
  "semanticHighlighting.enabled": ide,
1086
1495
  showDeprecated: ide,
1087
1496
  showUnused: ide,
@@ -1115,7 +1524,7 @@ function Code({
1115
1524
  // Don't select line when clicking line numbers
1116
1525
  wordBasedSuggestions: "off",
1117
1526
  // Reduce auto-completion interference
1118
- quickSuggestions: jsonSchema ? { strings: true, other: true, comments: false } : false,
1527
+ quickSuggestions: jsonSchema || intellisenseContext ? { strings: true, other: true, comments: false } : false,
1119
1528
  stickyScroll: { enabled: sticky }
1120
1529
  }
1121
1530
  }
@@ -1146,6 +1555,8 @@ function CodeBox({
1146
1555
  showCopy = true,
1147
1556
  showFormat = false,
1148
1557
  showSettings = false,
1558
+ // Validation
1559
+ onValidationIssues,
1149
1560
  // Layout
1150
1561
  footer,
1151
1562
  height,
@@ -1153,6 +1564,7 @@ function CodeBox({
1153
1564
  className,
1154
1565
  ...codeProps
1155
1566
  }) {
1567
+ const { onMount: userOnMount, ...restCodeProps } = codeProps;
1156
1568
  const [copied, setCopied] = useState4(false);
1157
1569
  const [showSettingsPanel, setShowSettingsPanel] = useState4(false);
1158
1570
  const [settings, setSettings] = useState4({
@@ -1162,6 +1574,9 @@ function CodeBox({
1162
1574
  sticky: true
1163
1575
  });
1164
1576
  const settingsRef = useRef4(null);
1577
+ const [markerCounts, setMarkerCounts] = useState4({ errors: 0, warnings: 0 });
1578
+ const editorInstanceRef = useRef4(null);
1579
+ const lastJumpIndexRef = useRef4({ errors: -1, warnings: -1 });
1165
1580
  useEffect3(() => {
1166
1581
  if (!showSettingsPanel) return;
1167
1582
  const handleClickOutside = (e) => {
@@ -1204,6 +1619,42 @@ function CodeBox({
1204
1619
  } catch (e) {
1205
1620
  }
1206
1621
  };
1622
+ const handleEditorMount = useCallback3(
1623
+ (monacoEditor) => {
1624
+ editorInstanceRef.current = monacoEditor;
1625
+ userOnMount?.(monacoEditor);
1626
+ },
1627
+ [userOnMount]
1628
+ );
1629
+ const handleMarkerCounts = useCallback3(
1630
+ (counts) => {
1631
+ setMarkerCounts(counts);
1632
+ lastJumpIndexRef.current = { errors: -1, warnings: -1 };
1633
+ onValidationIssues?.(counts);
1634
+ },
1635
+ [onValidationIssues]
1636
+ );
1637
+ const jumpToMarker = useCallback3((severity) => {
1638
+ const ed = editorInstanceRef.current;
1639
+ if (!ed) return;
1640
+ const model = ed.getModel();
1641
+ if (!model) return;
1642
+ const severityValue = severity === "error" ? 8 : 4;
1643
+ const markers = monacoNs.editor.getModelMarkers({ resource: model.uri }).filter((m) => m.severity === severityValue).sort(
1644
+ (a, b) => a.startLineNumber - b.startLineNumber || a.startColumn - b.startColumn
1645
+ );
1646
+ if (markers.length === 0) return;
1647
+ const key = severity === "error" ? "errors" : "warnings";
1648
+ const nextIndex = (lastJumpIndexRef.current[key] + 1) % markers.length;
1649
+ lastJumpIndexRef.current[key] = nextIndex;
1650
+ const marker = markers[nextIndex];
1651
+ ed.revealLineInCenter(marker.startLineNumber);
1652
+ ed.setPosition({
1653
+ lineNumber: marker.startLineNumber,
1654
+ column: marker.startColumn
1655
+ });
1656
+ ed.focus();
1657
+ }, []);
1207
1658
  const settingsProps = {
1208
1659
  lineNumbers: settings.lineNumbers,
1209
1660
  minimap: settings.minimap,
@@ -1211,6 +1662,60 @@ function CodeBox({
1211
1662
  sticky: settings.sticky
1212
1663
  };
1213
1664
  const actions = /* @__PURE__ */ jsxs3("div", { style: { display: "flex", gap: "4px", alignItems: "center" }, children: [
1665
+ markerCounts.errors > 0 && /* @__PURE__ */ jsxs3(
1666
+ "button",
1667
+ {
1668
+ className: "elb-codebox-marker-badge elb-codebox-marker-badge--error",
1669
+ onClick: () => jumpToMarker("error"),
1670
+ title: `${markerCounts.errors} error${markerCounts.errors !== 1 ? "s" : ""} \u2014 click to jump`,
1671
+ children: [
1672
+ /* @__PURE__ */ jsxs3(
1673
+ "svg",
1674
+ {
1675
+ width: "14",
1676
+ height: "14",
1677
+ viewBox: "0 0 24 24",
1678
+ fill: "none",
1679
+ stroke: "currentColor",
1680
+ strokeWidth: "2",
1681
+ children: [
1682
+ /* @__PURE__ */ jsx4("circle", { cx: "12", cy: "12", r: "10" }),
1683
+ /* @__PURE__ */ jsx4("line", { x1: "15", y1: "9", x2: "9", y2: "15" }),
1684
+ /* @__PURE__ */ jsx4("line", { x1: "9", y1: "9", x2: "15", y2: "15" })
1685
+ ]
1686
+ }
1687
+ ),
1688
+ /* @__PURE__ */ jsx4("span", { children: markerCounts.errors })
1689
+ ]
1690
+ }
1691
+ ),
1692
+ markerCounts.warnings > 0 && /* @__PURE__ */ jsxs3(
1693
+ "button",
1694
+ {
1695
+ className: "elb-codebox-marker-badge elb-codebox-marker-badge--warning",
1696
+ onClick: () => jumpToMarker("warning"),
1697
+ title: `${markerCounts.warnings} warning${markerCounts.warnings !== 1 ? "s" : ""} \u2014 click to jump`,
1698
+ children: [
1699
+ /* @__PURE__ */ jsxs3(
1700
+ "svg",
1701
+ {
1702
+ width: "14",
1703
+ height: "14",
1704
+ viewBox: "0 0 24 24",
1705
+ fill: "none",
1706
+ stroke: "currentColor",
1707
+ strokeWidth: "2",
1708
+ children: [
1709
+ /* @__PURE__ */ jsx4("path", { d: "M12 3L2 21h20L12 3z" }),
1710
+ /* @__PURE__ */ jsx4("line", { x1: "12", y1: "9", x2: "12", y2: "13" }),
1711
+ /* @__PURE__ */ jsx4("line", { x1: "12", y1: "17", x2: "12.01", y2: "17" })
1712
+ ]
1713
+ }
1714
+ ),
1715
+ /* @__PURE__ */ jsx4("span", { children: markerCounts.warnings })
1716
+ ]
1717
+ }
1718
+ ),
1214
1719
  showFormat && !disabled && currentLanguage === "json" && /* @__PURE__ */ jsx4(
1215
1720
  "button",
1216
1721
  {
@@ -1363,7 +1868,9 @@ function CodeBox({
1363
1868
  onChange,
1364
1869
  disabled,
1365
1870
  autoHeight,
1366
- ...codeProps,
1871
+ onMount: handleEditorMount,
1872
+ onMarkerCounts: handleMarkerCounts,
1873
+ ...restCodeProps,
1367
1874
  ...settingsProps
1368
1875
  }
1369
1876
  )
@@ -1391,7 +1898,9 @@ function CodeBox({
1391
1898
  onChange,
1392
1899
  disabled,
1393
1900
  autoHeight,
1394
- ...codeProps,
1901
+ onMount: handleEditorMount,
1902
+ onMarkerCounts: handleMarkerCounts,
1903
+ ...restCodeProps,
1395
1904
  ...settingsProps
1396
1905
  }
1397
1906
  )
@@ -2058,7 +2567,9 @@ function Preview({
2058
2567
  setTimeout(async () => {
2059
2568
  if (sourceRef.current) {
2060
2569
  try {
2061
- await sourceRef.current.destroy?.();
2570
+ await sourceRef.current.instance.destroy?.(
2571
+ sourceRef.current.destroyContext
2572
+ );
2062
2573
  } catch {
2063
2574
  }
2064
2575
  }
@@ -2083,34 +2594,44 @@ function Preview({
2083
2594
  ok: true,
2084
2595
  destination: {}
2085
2596
  });
2086
- const source = await sourceBrowser({
2597
+ const config = {
2598
+ settings: {
2599
+ pageview: false,
2600
+ prefix: "data-elb",
2601
+ elb: "elb",
2602
+ elbLayer: "elbLayer",
2603
+ // Use body as scope - trigger.ts compares `scope !== document` against
2604
+ // main page's document, so iframe.contentDocument fails the Element cast
2605
+ scope: iframe.contentDocument.body
2606
+ }
2607
+ };
2608
+ const env = {
2609
+ elb: elbRef.current,
2610
+ push: noopPush,
2611
+ command: async () => ({ ok: true, destination: {} }),
2612
+ logger: noopLogger,
2613
+ window: iframe.contentWindow,
2614
+ document: iframe.contentDocument
2615
+ };
2616
+ const instance = await sourceBrowser({
2087
2617
  id: "preview",
2088
2618
  collector: {},
2089
2619
  // Not used when elb is provided directly
2090
2620
  logger: noopLogger,
2091
2621
  setIngest: async () => {
2092
2622
  },
2093
- config: {
2094
- settings: {
2095
- pageview: false,
2096
- prefix: "data-elb",
2097
- elb: "elb",
2098
- elbLayer: "elbLayer",
2099
- // Use body as scope - trigger.ts compares `scope !== document` against
2100
- // main page's document, so iframe.contentDocument fails the Element cast
2101
- scope: iframe.contentDocument.body
2102
- }
2103
- },
2104
- env: {
2105
- elb: elbRef.current,
2106
- push: noopPush,
2107
- command: async () => ({ ok: true, destination: {} }),
2108
- logger: noopLogger,
2109
- window: iframe.contentWindow,
2110
- document: iframe.contentDocument
2111
- }
2623
+ config,
2624
+ env
2112
2625
  });
2113
- sourceRef.current = source;
2626
+ sourceRef.current = {
2627
+ instance,
2628
+ destroyContext: {
2629
+ id: "preview",
2630
+ config,
2631
+ env,
2632
+ logger: noopLogger
2633
+ }
2634
+ };
2114
2635
  } catch {
2115
2636
  }
2116
2637
  }, 50);
@@ -2121,7 +2642,7 @@ function Preview({
2121
2642
  clearTimeout(updateTimeoutRef.current);
2122
2643
  }
2123
2644
  if (sourceRef.current) {
2124
- sourceRef.current.destroy?.();
2645
+ sourceRef.current.instance.destroy?.(sourceRef.current.destroyContext);
2125
2646
  }
2126
2647
  };
2127
2648
  }, [html, css, highlights, autoMarkProperties, elb]);
@@ -3392,14 +3913,14 @@ function detectNodeType(value, path, structure, schemas) {
3392
3913
  const schema = propertyDef && schemas ? resolveSchema(path.slice(propertyDefIndex), propertyDef, schemas) : void 0;
3393
3914
  if (schema) {
3394
3915
  const primitiveType = typeof value;
3395
- const isPrimitive = primitiveType === "string" || primitiveType === "number" || primitiveType === "boolean" || value === void 0 || value === null;
3916
+ const isPrimitive2 = primitiveType === "string" || primitiveType === "number" || primitiveType === "boolean" || value === void 0 || value === null;
3396
3917
  if (schema.type === "boolean" && (primitiveType === "boolean" || value === void 0 || value === null)) {
3397
3918
  return "boolean";
3398
3919
  }
3399
- if (schema.enum && Array.isArray(schema.enum) && schema.enum.length > 0 && isPrimitive) {
3920
+ if (schema.enum && Array.isArray(schema.enum) && schema.enum.length > 0 && isPrimitive2) {
3400
3921
  return "enum";
3401
3922
  }
3402
- if ((schema.type === "string" || schema.type === "number") && isPrimitive) {
3923
+ if ((schema.type === "string" || schema.type === "number") && isPrimitive2) {
3403
3924
  return "primitive";
3404
3925
  }
3405
3926
  if (schema.type === "array") {
@@ -17498,6 +18019,474 @@ function useDropdown() {
17498
18019
  containerRef
17499
18020
  };
17500
18021
  }
18022
+
18023
+ // src/utils/monaco-schema-enrichment.ts
18024
+ function enrichSchema(baseSchema, enrichments) {
18025
+ const schema = JSON.parse(JSON.stringify(baseSchema));
18026
+ for (const [path, extensions] of Object.entries(enrichments)) {
18027
+ const target = path === "" ? schema : getNestedObject(schema, path);
18028
+ if (target && typeof target === "object") {
18029
+ Object.assign(target, extensions);
18030
+ }
18031
+ }
18032
+ return schema;
18033
+ }
18034
+ function getNestedObject(obj, path) {
18035
+ const keys = path.split(".");
18036
+ let current = obj;
18037
+ for (const key of keys) {
18038
+ if (current && typeof current === "object" && key in current) {
18039
+ current = current[key];
18040
+ } else {
18041
+ return void 0;
18042
+ }
18043
+ }
18044
+ return current;
18045
+ }
18046
+
18047
+ // src/utils/monaco-schema-flow-setup.ts
18048
+ function enrichFlowSetupSchema(baseSchema) {
18049
+ const schema = JSON.parse(JSON.stringify(baseSchema));
18050
+ if (!schema.anyOf?.[0]?.properties) return schema;
18051
+ const root = schema.anyOf[0];
18052
+ const props = root.properties;
18053
+ const flowConfig = props.flows?.additionalProperties?.properties;
18054
+ if (props.version) {
18055
+ props.version.markdownDescription = 'Schema version number. Must be `1` for the current format.\n\n```json\n"version": 1\n```';
18056
+ }
18057
+ if (props.$schema) {
18058
+ props.$schema.markdownDescription = 'JSON Schema URI for IDE validation.\n\n```json\n"$schema": "https://walkeros.io/schema/flow/v1.json"\n```';
18059
+ }
18060
+ if (props.include) {
18061
+ props.include.markdownDescription = 'Folders to include in the bundle output.\n\n```json\n"include": ["./src", "./lib"]\n```';
18062
+ }
18063
+ if (props.variables) {
18064
+ props.variables.markdownDescription = 'Shared variables for `$var.name` interpolation across all flows.\n\n```json\n"variables": {\n "measurementId": "G-XXXXXXXXXX",\n "debug": false\n}\n```\n\nReference in any config value: `"$var.measurementId"`';
18065
+ props.variables.defaultSnippets = [
18066
+ {
18067
+ label: "Add variable",
18068
+ description: "New key-value variable",
18069
+ body: { "${1:name}": "${2:value}" }
18070
+ }
18071
+ ];
18072
+ }
18073
+ if (props.definitions) {
18074
+ props.definitions.markdownDescription = 'Reusable configuration fragments for `$def.name` references.\n\n```json\n"definitions": {\n "gaConfig": {\n "measurementId": "$var.trackingId"\n }\n}\n```\n\nReference in any config: `"$def.gaConfig"`';
18075
+ props.definitions.defaultSnippets = [
18076
+ {
18077
+ label: "Add definition",
18078
+ description: "New reusable config fragment",
18079
+ body: { "${1:name}": { "${2:key}": "${3:value}" } }
18080
+ }
18081
+ ];
18082
+ }
18083
+ if (props.flows) {
18084
+ props.flows.markdownDescription = 'Flow configurations keyed by name. Each flow defines a complete event pipeline.\n\n```json\n"flows": {\n "myFlow": {\n "web": {},\n "sources": { ... },\n "destinations": { ... }\n }\n}\n```';
18085
+ props.flows.defaultSnippets = [
18086
+ {
18087
+ label: "Web flow (basic)",
18088
+ description: "Minimal web flow with browser source",
18089
+ body: {
18090
+ "${1:myFlow}": {
18091
+ web: {},
18092
+ sources: {
18093
+ browser: { package: "@walkeros/web-source-browser" }
18094
+ },
18095
+ destinations: {}
18096
+ }
18097
+ }
18098
+ },
18099
+ {
18100
+ label: "Server flow (basic)",
18101
+ description: "Minimal server flow with Express source",
18102
+ body: {
18103
+ "${1:myFlow}": {
18104
+ server: {},
18105
+ sources: {
18106
+ express: { package: "@walkeros/server-source-express" }
18107
+ },
18108
+ destinations: {}
18109
+ }
18110
+ }
18111
+ },
18112
+ {
18113
+ label: "Web + GA4 flow",
18114
+ description: "Web flow with browser source and GA4 destination",
18115
+ body: {
18116
+ "${1:myFlow}": {
18117
+ web: {},
18118
+ sources: {
18119
+ browser: { package: "@walkeros/web-source-browser" }
18120
+ },
18121
+ destinations: {
18122
+ ga4: {
18123
+ package: "@walkeros/web-destination-ga4",
18124
+ config: {
18125
+ measurementId: "$var.${2:measurementId}"
18126
+ }
18127
+ }
18128
+ }
18129
+ }
18130
+ }
18131
+ }
18132
+ ];
18133
+ }
18134
+ if (flowConfig) {
18135
+ if (flowConfig.sources) {
18136
+ flowConfig.sources.markdownDescription = 'Source configurations for data capture, keyed by step name.\n\n```json\n"sources": {\n "browser": { "package": "@walkeros/web-source-browser" }\n}\n```';
18137
+ flowConfig.sources.defaultSnippets = [
18138
+ {
18139
+ label: "Add web source",
18140
+ description: "Browser source for web tracking",
18141
+ body: {
18142
+ "${1:browser}": {
18143
+ package: "@walkeros/web-source-browser"
18144
+ }
18145
+ }
18146
+ },
18147
+ {
18148
+ label: "Add server source",
18149
+ description: "Express source for server tracking",
18150
+ body: {
18151
+ "${1:express}": {
18152
+ package: "@walkeros/server-source-express"
18153
+ }
18154
+ }
18155
+ }
18156
+ ];
18157
+ }
18158
+ if (flowConfig.destinations) {
18159
+ flowConfig.destinations.markdownDescription = 'Destination configurations for data output, keyed by step name.\n\n```json\n"destinations": {\n "ga4": {\n "package": "@walkeros/web-destination-ga4",\n "config": { "measurementId": "$var.trackingId" }\n }\n}\n```';
18160
+ flowConfig.destinations.defaultSnippets = [
18161
+ {
18162
+ label: "Add GA4 destination",
18163
+ description: "Google Analytics 4 destination",
18164
+ body: {
18165
+ "${1:ga4}": {
18166
+ package: "@walkeros/web-destination-ga4",
18167
+ config: {
18168
+ measurementId: "$var.${2:measurementId}"
18169
+ }
18170
+ }
18171
+ }
18172
+ },
18173
+ {
18174
+ label: "Add custom destination",
18175
+ description: "Custom destination with inline code",
18176
+ body: {
18177
+ "${1:custom}": {
18178
+ code: {
18179
+ push: "$code:(event) => { ${2:// handle event} }"
18180
+ }
18181
+ }
18182
+ }
18183
+ }
18184
+ ];
18185
+ }
18186
+ if (flowConfig.transformers) {
18187
+ flowConfig.transformers.markdownDescription = 'Transformer configurations for event transformation, keyed by step name.\n\n```json\n"transformers": {\n "validator": {\n "code": { "push": "$code:(event) => event" }\n }\n}\n```';
18188
+ flowConfig.transformers.defaultSnippets = [
18189
+ {
18190
+ label: "Add transformer",
18191
+ description: "Inline transformer with code",
18192
+ body: {
18193
+ "${1:transformer}": {
18194
+ code: {
18195
+ push: "$code:(event) => { ${2:return event;} }"
18196
+ }
18197
+ }
18198
+ }
18199
+ }
18200
+ ];
18201
+ }
18202
+ if (flowConfig.web) {
18203
+ flowConfig.web.markdownDescription = 'Web platform configuration (browser-based). Mutually exclusive with `server`.\n\n```json\n"web": {\n "windowCollector": "collector",\n "windowElb": "elb"\n}\n```';
18204
+ }
18205
+ if (flowConfig.server) {
18206
+ flowConfig.server.markdownDescription = 'Server platform configuration (Node.js). Mutually exclusive with `web`.\n\n```json\n"server": {}\n```';
18207
+ }
18208
+ }
18209
+ return schema;
18210
+ }
18211
+
18212
+ // src/utils/monaco-schema-contract.ts
18213
+ function getEnrichedContractSchema() {
18214
+ return {
18215
+ type: "object",
18216
+ markdownDescription: 'walkerOS Data Contract. Defines entity\u2192action schemas for event validation.\n\n```json\n{\n "$tagging": 1,\n "page": {\n "view": {\n "type": "object",\n "properties": {\n "title": { "type": "string" }\n }\n }\n }\n}\n```',
18217
+ properties: {
18218
+ $tagging: {
18219
+ type: "number",
18220
+ markdownDescription: 'Contract version number. Increment when making breaking changes.\n\n```json\n"$tagging": 1\n```'
18221
+ }
18222
+ },
18223
+ additionalProperties: {
18224
+ type: "object",
18225
+ markdownDescription: "Entity name. Contains action\u2192schema mappings.",
18226
+ additionalProperties: {
18227
+ type: "object",
18228
+ markdownDescription: 'Action schema (JSON Schema). Defines valid event data for this entity+action.\n\n```json\n{\n "type": "object",\n "properties": {\n "name": { "type": "string" },\n "price": { "type": "number" }\n },\n "required": ["name"]\n}\n```',
18229
+ defaultSnippets: [
18230
+ {
18231
+ label: "Object schema",
18232
+ description: "Schema with typed properties",
18233
+ body: {
18234
+ type: "object",
18235
+ properties: {
18236
+ "${1:name}": { type: "${2:string}" }
18237
+ }
18238
+ }
18239
+ }
18240
+ ]
18241
+ },
18242
+ defaultSnippets: [
18243
+ {
18244
+ label: "Add action",
18245
+ description: "Action with event data schema",
18246
+ body: {
18247
+ "${1:action}": {
18248
+ type: "object",
18249
+ properties: {
18250
+ "${2:property}": { type: "${3:string}" }
18251
+ }
18252
+ }
18253
+ }
18254
+ }
18255
+ ]
18256
+ },
18257
+ defaultSnippets: [
18258
+ {
18259
+ label: "Entity with action",
18260
+ description: "New entity with one action and properties",
18261
+ body: {
18262
+ "${1:entity}": {
18263
+ "${2:action}": {
18264
+ type: "object",
18265
+ properties: {
18266
+ "${3:property}": { type: "${4:string}" }
18267
+ }
18268
+ }
18269
+ }
18270
+ }
18271
+ }
18272
+ ]
18273
+ };
18274
+ }
18275
+
18276
+ // src/utils/monaco-schema-variables.ts
18277
+ function getVariablesSchema() {
18278
+ return {
18279
+ type: "object",
18280
+ markdownDescription: 'Flow variables for `$var.name` interpolation. Values must be string, number, or boolean.\n\n```json\n{\n "measurementId": "G-XXXXXXXXXX",\n "debug": false,\n "batchSize": 10\n}\n```\n\nReference in any config value: `"$var.measurementId"`',
18281
+ additionalProperties: {
18282
+ oneOf: [{ type: "string" }, { type: "number" }, { type: "boolean" }]
18283
+ },
18284
+ defaultSnippets: [
18285
+ {
18286
+ label: "Add string variable",
18287
+ body: { "${1:name}": "${2:value}" }
18288
+ },
18289
+ {
18290
+ label: "Add boolean variable",
18291
+ body: { "${1:name}": "${2|true,false|}" }
18292
+ },
18293
+ {
18294
+ label: "Add number variable",
18295
+ body: { "${1:name}": 0 }
18296
+ }
18297
+ ]
18298
+ };
18299
+ }
18300
+
18301
+ // src/utils/monaco-walkeros-markers.ts
18302
+ function validateWalkerOSReferences(text, context) {
18303
+ const issues = [];
18304
+ if (context.variables) {
18305
+ const varRegex = /\$var\.(\w+)/g;
18306
+ let match;
18307
+ while ((match = varRegex.exec(text)) !== null) {
18308
+ if (!(match[1] in context.variables)) {
18309
+ issues.push({
18310
+ message: `Unknown variable "$var.${match[1]}". Defined variables: ${Object.keys(context.variables).join(", ") || "none"}`,
18311
+ severity: "warning",
18312
+ startIndex: match.index,
18313
+ endIndex: match.index + match[0].length
18314
+ });
18315
+ }
18316
+ }
18317
+ }
18318
+ if (context.definitions) {
18319
+ const defRegex = /\$def\.(\w+)/g;
18320
+ let match;
18321
+ while ((match = defRegex.exec(text)) !== null) {
18322
+ if (!(match[1] in context.definitions)) {
18323
+ issues.push({
18324
+ message: `Unknown definition "$def.${match[1]}". Defined: ${Object.keys(context.definitions).join(", ") || "none"}`,
18325
+ severity: "warning",
18326
+ startIndex: match.index,
18327
+ endIndex: match.index + match[0].length
18328
+ });
18329
+ }
18330
+ }
18331
+ }
18332
+ if (context.secrets) {
18333
+ const secretRegex = /\$secret\.(\w+)/g;
18334
+ let match;
18335
+ while ((match = secretRegex.exec(text)) !== null) {
18336
+ if (!context.secrets.includes(match[1])) {
18337
+ issues.push({
18338
+ message: `Unknown secret "$secret.${match[1]}". Available: ${context.secrets.join(", ") || "none"}`,
18339
+ severity: "warning",
18340
+ startIndex: match.index,
18341
+ endIndex: match.index + match[0].length
18342
+ });
18343
+ }
18344
+ }
18345
+ }
18346
+ if (context.stepNames?.transformers) {
18347
+ const nextRegex = /"(?:next|before)"\s*:\s*"(\w+)"/g;
18348
+ let match;
18349
+ while ((match = nextRegex.exec(text)) !== null) {
18350
+ if (!context.stepNames.transformers.includes(match[1])) {
18351
+ issues.push({
18352
+ message: `Unknown transformer "${match[1]}". Available: ${context.stepNames.transformers.join(", ") || "none"}`,
18353
+ severity: "warning",
18354
+ startIndex: match.index,
18355
+ endIndex: match.index + match[0].length
18356
+ });
18357
+ }
18358
+ }
18359
+ }
18360
+ return issues;
18361
+ }
18362
+
18363
+ // src/utils/monaco-intellisense-flow-extractor.ts
18364
+ function extractFlowIntelliSenseContext(json2) {
18365
+ let parsed;
18366
+ try {
18367
+ parsed = JSON.parse(json2);
18368
+ } catch {
18369
+ return {};
18370
+ }
18371
+ if (!isFlowSetup(parsed)) return {};
18372
+ const variables = {};
18373
+ const definitions = {};
18374
+ const sources = [];
18375
+ const destinations = [];
18376
+ const transformers = [];
18377
+ const packages = [];
18378
+ const contractEntities = [];
18379
+ let platform;
18380
+ mergeVars(variables, parsed.variables);
18381
+ mergeDefs(definitions, parsed.definitions);
18382
+ extractContract(contractEntities, parsed.contract);
18383
+ for (const config of Object.values(parsed.flows)) {
18384
+ if (!isObject(config)) continue;
18385
+ if (!platform) {
18386
+ if ("web" in config) platform = "web";
18387
+ else if ("server" in config) platform = "server";
18388
+ }
18389
+ mergeVars(variables, config.variables);
18390
+ mergeDefs(definitions, config.definitions);
18391
+ extractContract(contractEntities, config.contract);
18392
+ if (isObject(config.sources)) {
18393
+ for (const [name, ref] of Object.entries(config.sources)) {
18394
+ sources.push(name);
18395
+ if (isObject(ref)) {
18396
+ mergeVars(variables, ref.variables);
18397
+ mergeDefs(definitions, ref.definitions);
18398
+ if (typeof ref.package === "string") {
18399
+ packages.push({
18400
+ package: ref.package,
18401
+ shortName: name,
18402
+ type: "source",
18403
+ platform: platform || "web"
18404
+ });
18405
+ }
18406
+ }
18407
+ }
18408
+ }
18409
+ if (isObject(config.destinations)) {
18410
+ for (const [name, ref] of Object.entries(config.destinations)) {
18411
+ destinations.push(name);
18412
+ if (isObject(ref)) {
18413
+ mergeVars(variables, ref.variables);
18414
+ mergeDefs(definitions, ref.definitions);
18415
+ if (typeof ref.package === "string") {
18416
+ packages.push({
18417
+ package: ref.package,
18418
+ shortName: name,
18419
+ type: "destination",
18420
+ platform: platform || "web"
18421
+ });
18422
+ }
18423
+ }
18424
+ }
18425
+ }
18426
+ if (isObject(config.transformers)) {
18427
+ for (const [name, ref] of Object.entries(config.transformers)) {
18428
+ transformers.push(name);
18429
+ if (isObject(ref)) {
18430
+ mergeVars(variables, ref.variables);
18431
+ mergeDefs(definitions, ref.definitions);
18432
+ if (typeof ref.package === "string") {
18433
+ packages.push({
18434
+ package: ref.package,
18435
+ shortName: name,
18436
+ type: "transformer",
18437
+ platform: platform || "web"
18438
+ });
18439
+ }
18440
+ }
18441
+ }
18442
+ }
18443
+ }
18444
+ const result = {
18445
+ variables,
18446
+ definitions,
18447
+ stepNames: { sources, destinations, transformers }
18448
+ };
18449
+ if (platform) result.platform = platform;
18450
+ if (packages.length > 0) result.packages = packages;
18451
+ if (contractEntities.length > 0) result.contract = contractEntities;
18452
+ return result;
18453
+ }
18454
+ function isObject(v) {
18455
+ return typeof v === "object" && v !== null && !Array.isArray(v);
18456
+ }
18457
+ function isFlowSetup(v) {
18458
+ return isObject(v) && "version" in v && "flows" in v && isObject(v.flows);
18459
+ }
18460
+ function isPrimitive(v) {
18461
+ return typeof v === "string" || typeof v === "number" || typeof v === "boolean";
18462
+ }
18463
+ function mergeVars(target, source) {
18464
+ if (!isObject(source)) return;
18465
+ for (const [k, v] of Object.entries(source)) {
18466
+ if (isPrimitive(v)) target[k] = v;
18467
+ }
18468
+ }
18469
+ function mergeDefs(target, source) {
18470
+ if (!isObject(source)) return;
18471
+ for (const [k, v] of Object.entries(source)) {
18472
+ target[k] = v;
18473
+ }
18474
+ }
18475
+ function extractContract(target, contract) {
18476
+ if (!isObject(contract)) return;
18477
+ for (const [key, value] of Object.entries(contract)) {
18478
+ if (key.startsWith("$") || !isObject(value)) continue;
18479
+ const existing = target.find((e) => e.entity === key);
18480
+ const actions = Object.keys(value);
18481
+ if (existing) {
18482
+ for (const a of actions) {
18483
+ if (!existing.actions.includes(a)) existing.actions.push(a);
18484
+ }
18485
+ } else {
18486
+ target.push({ entity: key, actions });
18487
+ }
18488
+ }
18489
+ }
17501
18490
  export {
17502
18491
  Alert,
17503
18492
  ArchitectureFlow,
@@ -17542,9 +18531,11 @@ export {
17542
18531
  Preview,
17543
18532
  PromotionPlayground,
17544
18533
  PropertyTable,
18534
+ REFERENCE_PATTERNS,
17545
18535
  Spinner,
17546
18536
  SplitButton,
17547
18537
  SubmitButton,
18538
+ applyWalkerOSDecorations,
17548
18539
  captureDestinationPush,
17549
18540
  cn,
17550
18541
  createCaptureFn,
@@ -17552,8 +18543,15 @@ export {
17552
18543
  createGtagDestination,
17553
18544
  createPlausibleDestination,
17554
18545
  createRawCapture,
18546
+ disposeWalkerOSProviders,
18547
+ enrichFlowSetupSchema,
18548
+ enrichSchema,
18549
+ extractFlowIntelliSenseContext,
18550
+ findWalkerOSReferences,
17555
18551
  formatCapturedCalls,
17556
18552
  generateModelPath,
18553
+ getEnrichedContractSchema,
18554
+ getVariablesSchema,
17557
18555
  initializeMonacoTypes,
17558
18556
  lighthouseTheme,
17559
18557
  loadPackageTypes,
@@ -17563,8 +18561,13 @@ export {
17563
18561
  registerJsonSchema,
17564
18562
  registerLighthouseTheme,
17565
18563
  registerPalenightTheme,
18564
+ registerWalkerOSDecorationStyles,
18565
+ registerWalkerOSProviders,
17566
18566
  registerWalkerOSTypes,
18567
+ removeIntelliSenseContext,
18568
+ setIntelliSenseContext,
17567
18569
  unregisterJsonSchema,
17568
- useDropdown
18570
+ useDropdown,
18571
+ validateWalkerOSReferences
17569
18572
  };
17570
18573
  //# sourceMappingURL=index.mjs.map