@principal-ai/principal-view-cli 0.1.13 → 0.1.15

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/index.cjs CHANGED
@@ -13464,18 +13464,162 @@ function loadLibrary(principalViewsDir) {
13464
13464
  if (library && typeof library === "object") {
13465
13465
  return {
13466
13466
  nodeComponents: library.nodeComponents || {},
13467
- edgeComponents: library.edgeComponents || {}
13467
+ edgeComponents: library.edgeComponents || {},
13468
+ raw: library,
13469
+ path: libraryPath
13468
13470
  };
13469
13471
  }
13470
13472
  } catch {
13471
- return { nodeComponents: {}, edgeComponents: {} };
13473
+ return { nodeComponents: {}, edgeComponents: {}, raw: {}, path: libraryPath };
13472
13474
  }
13473
13475
  }
13474
13476
  }
13475
13477
  return null;
13476
13478
  }
13479
+ function validateLibrary(library) {
13480
+ const issues = [];
13481
+ const lib = library.raw;
13482
+ checkUnknownFields(lib, ALLOWED_LIBRARY_FIELDS.root, "", issues);
13483
+ if (lib.nodeComponents && typeof lib.nodeComponents === "object") {
13484
+ for (const [compId, compDef] of Object.entries(lib.nodeComponents)) {
13485
+ if (compDef && typeof compDef === "object") {
13486
+ const comp = compDef;
13487
+ checkUnknownFields(comp, ALLOWED_LIBRARY_FIELDS.nodeComponent, `nodeComponents.${compId}`, issues);
13488
+ if (comp.size && typeof comp.size === "object") {
13489
+ checkUnknownFields(comp.size, ALLOWED_LIBRARY_FIELDS.nodeComponentSize, `nodeComponents.${compId}.size`, issues);
13490
+ }
13491
+ if (comp.states && typeof comp.states === "object") {
13492
+ for (const [stateId, stateDef] of Object.entries(comp.states)) {
13493
+ if (stateDef && typeof stateDef === "object") {
13494
+ checkUnknownFields(stateDef, ALLOWED_LIBRARY_FIELDS.nodeComponentState, `nodeComponents.${compId}.states.${stateId}`, issues);
13495
+ }
13496
+ }
13497
+ }
13498
+ if (comp.dataSchema && typeof comp.dataSchema === "object") {
13499
+ for (const [fieldName, fieldDef] of Object.entries(comp.dataSchema)) {
13500
+ if (fieldDef && typeof fieldDef === "object") {
13501
+ checkUnknownFields(fieldDef, ALLOWED_LIBRARY_FIELDS.nodeComponentDataSchemaField, `nodeComponents.${compId}.dataSchema.${fieldName}`, issues);
13502
+ }
13503
+ }
13504
+ }
13505
+ if (comp.layout && typeof comp.layout === "object") {
13506
+ checkUnknownFields(comp.layout, ALLOWED_LIBRARY_FIELDS.nodeComponentLayout, `nodeComponents.${compId}.layout`, issues);
13507
+ }
13508
+ if (Array.isArray(comp.actions)) {
13509
+ comp.actions.forEach((action, actionIndex) => {
13510
+ if (action && typeof action === "object") {
13511
+ checkUnknownFields(action, ALLOWED_LIBRARY_FIELDS.nodeComponentAction, `nodeComponents.${compId}.actions[${actionIndex}]`, issues);
13512
+ }
13513
+ });
13514
+ }
13515
+ }
13516
+ }
13517
+ }
13518
+ if (lib.edgeComponents && typeof lib.edgeComponents === "object") {
13519
+ for (const [compId, compDef] of Object.entries(lib.edgeComponents)) {
13520
+ if (compDef && typeof compDef === "object") {
13521
+ const comp = compDef;
13522
+ checkUnknownFields(comp, ALLOWED_LIBRARY_FIELDS.edgeComponent, `edgeComponents.${compId}`, issues);
13523
+ if (comp.animation && typeof comp.animation === "object") {
13524
+ checkUnknownFields(comp.animation, ALLOWED_LIBRARY_FIELDS.edgeComponentAnimation, `edgeComponents.${compId}.animation`, issues);
13525
+ }
13526
+ if (comp.label && typeof comp.label === "object") {
13527
+ checkUnknownFields(comp.label, ALLOWED_LIBRARY_FIELDS.edgeComponentLabel, `edgeComponents.${compId}.label`, issues);
13528
+ }
13529
+ }
13530
+ }
13531
+ }
13532
+ if (Array.isArray(lib.connectionRules)) {
13533
+ lib.connectionRules.forEach((rule, ruleIndex) => {
13534
+ if (rule && typeof rule === "object") {
13535
+ const r = rule;
13536
+ checkUnknownFields(r, ALLOWED_LIBRARY_FIELDS.connectionRule, `connectionRules[${ruleIndex}]`, issues);
13537
+ if (r.constraints && typeof r.constraints === "object") {
13538
+ checkUnknownFields(r.constraints, ALLOWED_LIBRARY_FIELDS.connectionRuleConstraints, `connectionRules[${ruleIndex}].constraints`, issues);
13539
+ }
13540
+ }
13541
+ });
13542
+ }
13543
+ return issues;
13544
+ }
13477
13545
  var STANDARD_CANVAS_TYPES = ["text", "group", "file", "link"];
13478
13546
  var VALID_NODE_SHAPES = ["circle", "rectangle", "hexagon", "diamond", "custom"];
13547
+ var ALLOWED_CANVAS_FIELDS = {
13548
+ root: ["nodes", "edges", "pv"],
13549
+ pv: ["version", "name", "description", "nodeTypes", "edgeTypes", "pathConfig", "display"],
13550
+ pvPathConfig: ["projectRoot", "captureSource", "enableActionPatterns", "logLevel", "ignoreUnsourced"],
13551
+ pvDisplay: ["layout", "theme", "animations"],
13552
+ pvDisplayTheme: ["primary", "success", "warning", "danger", "info"],
13553
+ pvDisplayAnimations: ["enabled", "speed"],
13554
+ pvNodeType: ["label", "description", "color", "icon", "shape"],
13555
+ pvEdgeType: ["label", "style", "color", "width", "directed", "animation", "labelConfig", "activatedBy"],
13556
+ pvEdgeTypeAnimation: ["type", "duration", "color"],
13557
+ pvEdgeTypeLabelConfig: ["field", "position"],
13558
+ // Base node fields from JSON Canvas spec
13559
+ nodeBase: ["id", "type", "x", "y", "width", "height", "color", "pv"],
13560
+ // Type-specific node fields
13561
+ nodeText: ["text"],
13562
+ nodeFile: ["file", "subpath"],
13563
+ nodeLink: ["url"],
13564
+ nodeGroup: ["label", "background", "backgroundStyle"],
13565
+ // Node pv extension
13566
+ nodePv: ["nodeType", "description", "shape", "icon", "fill", "stroke", "states", "sources", "actions", "dataSchema", "layout"],
13567
+ nodePvState: ["color", "icon", "label"],
13568
+ nodePvAction: ["pattern", "event", "state", "metadata", "triggerEdges"],
13569
+ nodePvDataSchemaField: ["type", "required", "displayInLabel"],
13570
+ nodePvLayout: ["layer", "cluster"],
13571
+ // Edge fields
13572
+ edge: ["id", "fromNode", "toNode", "fromSide", "toSide", "fromEnd", "toEnd", "color", "label", "pv"],
13573
+ edgePv: ["edgeType", "style", "width", "animation", "activatedBy"],
13574
+ edgePvAnimation: ["type", "duration", "color"],
13575
+ edgePvActivatedBy: ["action", "animation", "direction", "duration"]
13576
+ };
13577
+ var ALLOWED_LIBRARY_FIELDS = {
13578
+ root: ["version", "name", "description", "nodeComponents", "edgeComponents", "connectionRules"],
13579
+ nodeComponent: ["description", "tags", "defaultLabel", "shape", "icon", "color", "size", "states", "sources", "actions", "dataSchema", "layout"],
13580
+ nodeComponentSize: ["width", "height"],
13581
+ nodeComponentState: ["color", "icon", "label"],
13582
+ nodeComponentAction: ["pattern", "event", "state", "metadata", "triggerEdges"],
13583
+ nodeComponentDataSchemaField: ["type", "required", "displayInLabel", "label", "displayInInfo"],
13584
+ nodeComponentLayout: ["layer", "cluster"],
13585
+ edgeComponent: ["description", "tags", "style", "color", "width", "directed", "animation", "label"],
13586
+ edgeComponentAnimation: ["type", "duration", "color"],
13587
+ edgeComponentLabel: ["field", "position"],
13588
+ connectionRule: ["from", "to", "via", "constraints"],
13589
+ connectionRuleConstraints: ["maxInstances", "bidirectional", "exclusive"]
13590
+ };
13591
+ function checkUnknownFields(obj, allowedFields, path4, issues) {
13592
+ for (const field of Object.keys(obj)) {
13593
+ if (!allowedFields.includes(field)) {
13594
+ const suggestion = findSimilarField(field, allowedFields);
13595
+ issues.push({
13596
+ type: "error",
13597
+ message: `Unknown field "${field}"${path4 ? ` in ${path4}` : " at root level"}`,
13598
+ path: path4 ? `${path4}.${field}` : field,
13599
+ suggestion: suggestion ? `Did you mean "${suggestion}"? Allowed fields: ${allowedFields.join(", ")}` : `Allowed fields: ${allowedFields.join(", ")}`
13600
+ });
13601
+ }
13602
+ }
13603
+ }
13604
+ function findSimilarField(field, allowedFields) {
13605
+ const fieldLower = field.toLowerCase();
13606
+ for (const allowed of allowedFields) {
13607
+ const allowedLower = allowed.toLowerCase();
13608
+ if (fieldLower.includes(allowedLower) || allowedLower.includes(fieldLower)) {
13609
+ return allowed;
13610
+ }
13611
+ if (Math.abs(field.length - allowed.length) <= 2) {
13612
+ let differences = 0;
13613
+ const minLen = Math.min(fieldLower.length, allowedLower.length);
13614
+ for (let i = 0; i < minLen; i++) {
13615
+ if (fieldLower[i] !== allowedLower[i]) differences++;
13616
+ }
13617
+ differences += Math.abs(field.length - allowed.length);
13618
+ if (differences <= 2) return allowed;
13619
+ }
13620
+ }
13621
+ return null;
13622
+ }
13479
13623
  function validateCanvas(canvas, filePath, library) {
13480
13624
  const issues = [];
13481
13625
  if (!canvas || typeof canvas !== "object") {
@@ -13483,6 +13627,7 @@ function validateCanvas(canvas, filePath, library) {
13483
13627
  return issues;
13484
13628
  }
13485
13629
  const c = canvas;
13630
+ checkUnknownFields(c, ALLOWED_CANVAS_FIELDS.root, "", issues);
13486
13631
  const libraryNodeTypes = library ? Object.keys(library.nodeComponents) : [];
13487
13632
  const libraryEdgeTypes = library ? Object.keys(library.edgeComponents) : [];
13488
13633
  let canvasEdgeTypes = [];
@@ -13498,6 +13643,7 @@ function validateCanvas(canvas, filePath, library) {
13498
13643
  issues.push({ type: "error", message: '"pv" extension must be an object' });
13499
13644
  } else {
13500
13645
  const pv = c.pv;
13646
+ checkUnknownFields(pv, ALLOWED_CANVAS_FIELDS.pv, "pv", issues);
13501
13647
  if (typeof pv.version !== "string" || !pv.version) {
13502
13648
  issues.push({
13503
13649
  type: "error",
@@ -13514,11 +13660,41 @@ function validateCanvas(canvas, filePath, library) {
13514
13660
  suggestion: 'Add: "name": "My Graph"'
13515
13661
  });
13516
13662
  }
13517
- if (pv.edgeTypes && typeof pv.edgeTypes === "object") {
13518
- canvasEdgeTypes = Object.keys(pv.edgeTypes);
13663
+ if (pv.pathConfig && typeof pv.pathConfig === "object") {
13664
+ checkUnknownFields(pv.pathConfig, ALLOWED_CANVAS_FIELDS.pvPathConfig, "pv.pathConfig", issues);
13665
+ }
13666
+ if (pv.display && typeof pv.display === "object") {
13667
+ const display = pv.display;
13668
+ checkUnknownFields(display, ALLOWED_CANVAS_FIELDS.pvDisplay, "pv.display", issues);
13669
+ if (display.theme && typeof display.theme === "object") {
13670
+ checkUnknownFields(display.theme, ALLOWED_CANVAS_FIELDS.pvDisplayTheme, "pv.display.theme", issues);
13671
+ }
13672
+ if (display.animations && typeof display.animations === "object") {
13673
+ checkUnknownFields(display.animations, ALLOWED_CANVAS_FIELDS.pvDisplayAnimations, "pv.display.animations", issues);
13674
+ }
13519
13675
  }
13520
13676
  if (pv.nodeTypes && typeof pv.nodeTypes === "object") {
13521
13677
  canvasNodeTypes = Object.keys(pv.nodeTypes);
13678
+ for (const [typeId, typeDef] of Object.entries(pv.nodeTypes)) {
13679
+ if (typeDef && typeof typeDef === "object") {
13680
+ checkUnknownFields(typeDef, ALLOWED_CANVAS_FIELDS.pvNodeType, `pv.nodeTypes.${typeId}`, issues);
13681
+ }
13682
+ }
13683
+ }
13684
+ if (pv.edgeTypes && typeof pv.edgeTypes === "object") {
13685
+ canvasEdgeTypes = Object.keys(pv.edgeTypes);
13686
+ for (const [typeId, typeDef] of Object.entries(pv.edgeTypes)) {
13687
+ if (typeDef && typeof typeDef === "object") {
13688
+ const edgeTypeDef = typeDef;
13689
+ checkUnknownFields(edgeTypeDef, ALLOWED_CANVAS_FIELDS.pvEdgeType, `pv.edgeTypes.${typeId}`, issues);
13690
+ if (edgeTypeDef.animation && typeof edgeTypeDef.animation === "object") {
13691
+ checkUnknownFields(edgeTypeDef.animation, ALLOWED_CANVAS_FIELDS.pvEdgeTypeAnimation, `pv.edgeTypes.${typeId}.animation`, issues);
13692
+ }
13693
+ if (edgeTypeDef.labelConfig && typeof edgeTypeDef.labelConfig === "object") {
13694
+ checkUnknownFields(edgeTypeDef.labelConfig, ALLOWED_CANVAS_FIELDS.pvEdgeTypeLabelConfig, `pv.edgeTypes.${typeId}.labelConfig`, issues);
13695
+ }
13696
+ }
13697
+ }
13522
13698
  }
13523
13699
  }
13524
13700
  const allDefinedNodeTypes = [.../* @__PURE__ */ new Set([...canvasNodeTypes, ...libraryNodeTypes])];
@@ -13532,25 +13708,38 @@ function validateCanvas(canvas, filePath, library) {
13532
13708
  return;
13533
13709
  }
13534
13710
  const n = node;
13711
+ const nodePath2 = `nodes[${index}]`;
13712
+ const nodeLabel = n.id || index;
13713
+ const nodeType = n.type;
13714
+ let allowedNodeFields = [...ALLOWED_CANVAS_FIELDS.nodeBase];
13715
+ if (nodeType === "text") {
13716
+ allowedNodeFields = [...allowedNodeFields, ...ALLOWED_CANVAS_FIELDS.nodeText];
13717
+ } else if (nodeType === "file") {
13718
+ allowedNodeFields = [...allowedNodeFields, ...ALLOWED_CANVAS_FIELDS.nodeFile];
13719
+ } else if (nodeType === "link") {
13720
+ allowedNodeFields = [...allowedNodeFields, ...ALLOWED_CANVAS_FIELDS.nodeLink];
13721
+ } else if (nodeType === "group") {
13722
+ allowedNodeFields = [...allowedNodeFields, ...ALLOWED_CANVAS_FIELDS.nodeGroup];
13723
+ }
13724
+ checkUnknownFields(n, allowedNodeFields, nodePath2, issues);
13535
13725
  if (typeof n.id !== "string" || !n.id) {
13536
- issues.push({ type: "error", message: `Node at index ${index} must have a string "id"`, path: `nodes[${index}].id` });
13726
+ issues.push({ type: "error", message: `Node at index ${index} must have a string "id"`, path: `${nodePath2}.id` });
13537
13727
  }
13538
13728
  if (typeof n.type !== "string") {
13539
- issues.push({ type: "error", message: `Node "${n.id || index}" must have a string "type"`, path: `nodes[${index}].type` });
13729
+ issues.push({ type: "error", message: `Node "${nodeLabel}" must have a string "type"`, path: `${nodePath2}.type` });
13540
13730
  }
13541
13731
  if (typeof n.x !== "number") {
13542
- issues.push({ type: "error", message: `Node "${n.id || index}" must have a numeric "x" position`, path: `nodes[${index}].x` });
13732
+ issues.push({ type: "error", message: `Node "${nodeLabel}" must have a numeric "x" position`, path: `${nodePath2}.x` });
13543
13733
  }
13544
13734
  if (typeof n.y !== "number") {
13545
- issues.push({ type: "error", message: `Node "${n.id || index}" must have a numeric "y" position`, path: `nodes[${index}].y` });
13735
+ issues.push({ type: "error", message: `Node "${nodeLabel}" must have a numeric "y" position`, path: `${nodePath2}.y` });
13546
13736
  }
13547
13737
  if (typeof n.width !== "number") {
13548
- issues.push({ type: "error", message: `Node "${n.id || index}" must have a numeric "width"`, path: `nodes[${index}].width` });
13738
+ issues.push({ type: "error", message: `Node "${nodeLabel}" must have a numeric "width"`, path: `${nodePath2}.width` });
13549
13739
  }
13550
13740
  if (typeof n.height !== "number") {
13551
- issues.push({ type: "error", message: `Node "${n.id || index}" must have a numeric "height"`, path: `nodes[${index}].height` });
13741
+ issues.push({ type: "error", message: `Node "${nodeLabel}" must have a numeric "height"`, path: `${nodePath2}.height` });
13552
13742
  }
13553
- const nodeType = n.type;
13554
13743
  const isStandardType = STANDARD_CANVAS_TYPES.includes(nodeType);
13555
13744
  if (!isStandardType) {
13556
13745
  if (!n.pv || typeof n.pv !== "object") {
@@ -13581,12 +13770,37 @@ function validateCanvas(canvas, filePath, library) {
13581
13770
  }
13582
13771
  if (n.pv && typeof n.pv === "object") {
13583
13772
  const nodePv = n.pv;
13773
+ checkUnknownFields(nodePv, ALLOWED_CANVAS_FIELDS.nodePv, `${nodePath2}.pv`, issues);
13774
+ if (nodePv.states && typeof nodePv.states === "object") {
13775
+ for (const [stateId, stateDef] of Object.entries(nodePv.states)) {
13776
+ if (stateDef && typeof stateDef === "object") {
13777
+ checkUnknownFields(stateDef, ALLOWED_CANVAS_FIELDS.nodePvState, `${nodePath2}.pv.states.${stateId}`, issues);
13778
+ }
13779
+ }
13780
+ }
13781
+ if (nodePv.dataSchema && typeof nodePv.dataSchema === "object") {
13782
+ for (const [fieldName, fieldDef] of Object.entries(nodePv.dataSchema)) {
13783
+ if (fieldDef && typeof fieldDef === "object") {
13784
+ checkUnknownFields(fieldDef, ALLOWED_CANVAS_FIELDS.nodePvDataSchemaField, `${nodePath2}.pv.dataSchema.${fieldName}`, issues);
13785
+ }
13786
+ }
13787
+ }
13788
+ if (nodePv.layout && typeof nodePv.layout === "object") {
13789
+ checkUnknownFields(nodePv.layout, ALLOWED_CANVAS_FIELDS.nodePvLayout, `${nodePath2}.pv.layout`, issues);
13790
+ }
13791
+ if (Array.isArray(nodePv.actions)) {
13792
+ nodePv.actions.forEach((action, actionIndex) => {
13793
+ if (action && typeof action === "object") {
13794
+ checkUnknownFields(action, ALLOWED_CANVAS_FIELDS.nodePvAction, `${nodePath2}.pv.actions[${actionIndex}]`, issues);
13795
+ }
13796
+ });
13797
+ }
13584
13798
  if (typeof nodePv.nodeType === "string" && nodePv.nodeType) {
13585
13799
  if (allDefinedNodeTypes.length === 0) {
13586
13800
  issues.push({
13587
13801
  type: "error",
13588
- message: `Node "${n.id || index}" uses nodeType "${nodePv.nodeType}" but no node types are defined`,
13589
- path: `nodes[${index}].pv.nodeType`,
13802
+ message: `Node "${nodeLabel}" uses nodeType "${nodePv.nodeType}" but no node types are defined`,
13803
+ path: `${nodePath2}.pv.nodeType`,
13590
13804
  suggestion: "Define node types in canvas pv.nodeTypes or library.yaml nodeComponents"
13591
13805
  });
13592
13806
  } else if (!allDefinedNodeTypes.includes(nodePv.nodeType)) {
@@ -13600,8 +13814,8 @@ function validateCanvas(canvas, filePath, library) {
13600
13814
  const suggestion = sources.length > 0 ? `Available types from ${sources.join(" | ")}` : "Define node types in canvas pv.nodeTypes or library.yaml nodeComponents";
13601
13815
  issues.push({
13602
13816
  type: "error",
13603
- message: `Node "${n.id || index}" uses undefined nodeType "${nodePv.nodeType}"`,
13604
- path: `nodes[${index}].pv.nodeType`,
13817
+ message: `Node "${nodeLabel}" uses undefined nodeType "${nodePv.nodeType}"`,
13818
+ path: `${nodePath2}.pv.nodeType`,
13605
13819
  suggestion
13606
13820
  });
13607
13821
  }
@@ -13619,27 +13833,41 @@ function validateCanvas(canvas, filePath, library) {
13619
13833
  return;
13620
13834
  }
13621
13835
  const e = edge;
13836
+ const edgePath = `edges[${index}]`;
13837
+ const edgeLabel = e.id || index;
13838
+ checkUnknownFields(e, ALLOWED_CANVAS_FIELDS.edge, edgePath, issues);
13622
13839
  if (typeof e.id !== "string" || !e.id) {
13623
- issues.push({ type: "error", message: `Edge at index ${index} must have a string "id"`, path: `edges[${index}].id` });
13840
+ issues.push({ type: "error", message: `Edge at index ${index} must have a string "id"`, path: `${edgePath}.id` });
13624
13841
  }
13625
13842
  if (typeof e.fromNode !== "string") {
13626
- issues.push({ type: "error", message: `Edge "${e.id || index}" must have a string "fromNode"`, path: `edges[${index}].fromNode` });
13843
+ issues.push({ type: "error", message: `Edge "${edgeLabel}" must have a string "fromNode"`, path: `${edgePath}.fromNode` });
13627
13844
  } else if (!nodeIds.has(e.fromNode)) {
13628
- issues.push({ type: "error", message: `Edge "${e.id || index}" references unknown node "${e.fromNode}"`, path: `edges[${index}].fromNode` });
13845
+ issues.push({ type: "error", message: `Edge "${edgeLabel}" references unknown node "${e.fromNode}"`, path: `${edgePath}.fromNode` });
13629
13846
  }
13630
13847
  if (typeof e.toNode !== "string") {
13631
- issues.push({ type: "error", message: `Edge "${e.id || index}" must have a string "toNode"`, path: `edges[${index}].toNode` });
13848
+ issues.push({ type: "error", message: `Edge "${edgeLabel}" must have a string "toNode"`, path: `${edgePath}.toNode` });
13632
13849
  } else if (!nodeIds.has(e.toNode)) {
13633
- issues.push({ type: "error", message: `Edge "${e.id || index}" references unknown node "${e.toNode}"`, path: `edges[${index}].toNode` });
13850
+ issues.push({ type: "error", message: `Edge "${edgeLabel}" references unknown node "${e.toNode}"`, path: `${edgePath}.toNode` });
13634
13851
  }
13635
13852
  if (e.pv && typeof e.pv === "object") {
13636
13853
  const edgePv = e.pv;
13854
+ checkUnknownFields(edgePv, ALLOWED_CANVAS_FIELDS.edgePv, `${edgePath}.pv`, issues);
13855
+ if (edgePv.animation && typeof edgePv.animation === "object") {
13856
+ checkUnknownFields(edgePv.animation, ALLOWED_CANVAS_FIELDS.edgePvAnimation, `${edgePath}.pv.animation`, issues);
13857
+ }
13858
+ if (Array.isArray(edgePv.activatedBy)) {
13859
+ edgePv.activatedBy.forEach((trigger, triggerIndex) => {
13860
+ if (trigger && typeof trigger === "object") {
13861
+ checkUnknownFields(trigger, ALLOWED_CANVAS_FIELDS.edgePvActivatedBy, `${edgePath}.pv.activatedBy[${triggerIndex}]`, issues);
13862
+ }
13863
+ });
13864
+ }
13637
13865
  if (edgePv.edgeType && typeof edgePv.edgeType === "string") {
13638
13866
  if (allDefinedEdgeTypes.length === 0) {
13639
13867
  issues.push({
13640
13868
  type: "error",
13641
- message: `Edge "${e.id || index}" uses edgeType "${edgePv.edgeType}" but no edge types are defined`,
13642
- path: `edges[${index}].pv.edgeType`,
13869
+ message: `Edge "${edgeLabel}" uses edgeType "${edgePv.edgeType}" but no edge types are defined`,
13870
+ path: `${edgePath}.pv.edgeType`,
13643
13871
  suggestion: "Define edge types in canvas pv.edgeTypes or library.yaml edgeComponents"
13644
13872
  });
13645
13873
  } else if (!allDefinedEdgeTypes.includes(edgePv.edgeType)) {
@@ -13653,8 +13881,8 @@ function validateCanvas(canvas, filePath, library) {
13653
13881
  const suggestion = sources.length > 0 ? `Available types from ${sources.join(" | ")}` : "Define edge types in canvas pv.edgeTypes or library.yaml edgeComponents";
13654
13882
  issues.push({
13655
13883
  type: "error",
13656
- message: `Edge "${e.id || index}" uses undefined edgeType "${edgePv.edgeType}"`,
13657
- path: `edges[${index}].pv.edgeType`,
13884
+ message: `Edge "${edgeLabel}" uses undefined edgeType "${edgePv.edgeType}"`,
13885
+ path: `${edgePath}.pv.edgeType`,
13658
13886
  suggestion
13659
13887
  });
13660
13888
  }
@@ -13713,21 +13941,33 @@ function createValidateCommand() {
13713
13941
  }
13714
13942
  const principalViewsDir = (0, import_node_path5.resolve)(process.cwd(), ".principal-views");
13715
13943
  const library = loadLibrary(principalViewsDir);
13944
+ let libraryResult = null;
13945
+ if (library && Object.keys(library.raw).length > 0) {
13946
+ const libraryIssues = validateLibrary(library);
13947
+ const libraryHasErrors = libraryIssues.some((i) => i.type === "error");
13948
+ libraryResult = {
13949
+ file: (0, import_node_path5.relative)(process.cwd(), library.path),
13950
+ isValid: !libraryHasErrors,
13951
+ issues: libraryIssues
13952
+ };
13953
+ }
13716
13954
  const results = matchedFiles.map((f) => validateFile(f, library));
13717
- const validCount = results.filter((r) => r.isValid).length;
13718
- const invalidCount = results.length - validCount;
13955
+ const allResults = libraryResult ? [libraryResult, ...results] : results;
13956
+ const validCount = allResults.filter((r) => r.isValid).length;
13957
+ const invalidCount = allResults.length - validCount;
13719
13958
  if (options.json) {
13720
13959
  console.log(JSON.stringify({
13721
- files: results,
13722
- summary: { total: results.length, valid: validCount, invalid: invalidCount }
13960
+ files: allResults,
13961
+ summary: { total: allResults.length, valid: validCount, invalid: invalidCount }
13723
13962
  }, null, 2));
13724
13963
  } else {
13725
13964
  if (!options.quiet) {
13965
+ const fileCount = libraryResult ? `${results.length} canvas file(s) + library` : `${results.length} canvas file(s)`;
13726
13966
  console.log(source_default.bold(`
13727
- Validating ${results.length} canvas file(s)...
13967
+ Validating ${fileCount}...
13728
13968
  `));
13729
13969
  }
13730
- for (const result of results) {
13970
+ for (const result of allResults) {
13731
13971
  if (result.isValid) {
13732
13972
  if (!options.quiet) {
13733
13973
  console.log(source_default.green(`\u2713 ${result.file}`));
@@ -13754,7 +13994,7 @@ Validating ${results.length} canvas file(s)...
13754
13994
  if (invalidCount === 0) {
13755
13995
  console.log(source_default.green(`\u2713 All ${validCount} file(s) are valid`));
13756
13996
  } else {
13757
- console.log(source_default.red(`\u2717 ${invalidCount} of ${results.length} file(s) failed validation`));
13997
+ console.log(source_default.red(`\u2717 ${invalidCount} of ${allResults.length} file(s) failed validation`));
13758
13998
  process.exit(1);
13759
13999
  }
13760
14000
  }
@@ -14915,19 +15155,19 @@ var ConfigurationLoader = class _ConfigurationLoader {
14915
15155
  this.fsAdapter = fsAdapter;
14916
15156
  }
14917
15157
  /**
14918
- * Check if the .vgc/ configuration directory exists
15158
+ * Check if the .principal-views/ configuration directory exists
14919
15159
  *
14920
15160
  * @param baseDir - Base directory to search from
14921
- * @returns True if .vgc/ directory exists
15161
+ * @returns True if .principal-views/ directory exists
14922
15162
  */
14923
15163
  hasConfigDirectory(baseDir) {
14924
15164
  const configPath = this.fsAdapter.join(baseDir, _ConfigurationLoader.CONFIG_DIR);
14925
15165
  return this.fsAdapter.exists(configPath) && this.fsAdapter.isDirectory(configPath);
14926
15166
  }
14927
15167
  /**
14928
- * List all available configuration names in .vgc/ folder
15168
+ * List all available configuration names in .principal-views/ folder
14929
15169
  *
14930
- * @param baseDir - Base directory containing .vgc/ folder
15170
+ * @param baseDir - Base directory containing .principal-views/ folder
14931
15171
  * @returns Array of configuration names (without extensions)
14932
15172
  */
14933
15173
  listConfigurations(baseDir) {
@@ -14942,7 +15182,7 @@ var ConfigurationLoader = class _ConfigurationLoader {
14942
15182
  * Load a specific configuration by name
14943
15183
  *
14944
15184
  * @param name - Configuration name (without extension)
14945
- * @param baseDir - Base directory containing .vgc/ folder
15185
+ * @param baseDir - Base directory containing .principal-views/ folder
14946
15186
  * @returns Configuration file or null if not found/invalid
14947
15187
  */
14948
15188
  loadByName(name, baseDir) {
@@ -14972,9 +15212,9 @@ var ConfigurationLoader = class _ConfigurationLoader {
14972
15212
  return null;
14973
15213
  }
14974
15214
  /**
14975
- * Load all configurations from .vgc/ folder
15215
+ * Load all configurations from .principal-views/ folder
14976
15216
  *
14977
- * @param baseDir - Base directory containing .vgc/ folder
15217
+ * @param baseDir - Base directory containing .principal-views/ folder
14978
15218
  * @returns Result containing all loaded configs and any errors
14979
15219
  */
14980
15220
  loadAll(baseDir) {
@@ -14984,8 +15224,8 @@ var ConfigurationLoader = class _ConfigurationLoader {
14984
15224
  };
14985
15225
  if (!this.hasConfigDirectory(baseDir)) {
14986
15226
  result.errors.push({
14987
- file: ".vgc",
14988
- error: "Configuration directory .vgc/ not found"
15227
+ file: ".principal-views",
15228
+ error: "Configuration directory .principal-views/ not found"
14989
15229
  });
14990
15230
  return result;
14991
15231
  }
@@ -15027,13 +15267,13 @@ var ConfigurationLoader = class _ConfigurationLoader {
15027
15267
  * Get the configuration directory path
15028
15268
  *
15029
15269
  * @param baseDir - Base directory
15030
- * @returns Full path to .vgc/ directory
15270
+ * @returns Full path to .principal-views/ directory
15031
15271
  */
15032
15272
  getConfigDirectoryPath(baseDir) {
15033
15273
  return this.fsAdapter.join(baseDir, _ConfigurationLoader.CONFIG_DIR);
15034
15274
  }
15035
15275
  };
15036
- ConfigurationLoader.CONFIG_DIR = ".vgc";
15276
+ ConfigurationLoader.CONFIG_DIR = ".principal-views";
15037
15277
 
15038
15278
  // ../core/dist/rules/types.js
15039
15279
  function normalizeSeverity(severity) {
@@ -15270,7 +15510,7 @@ function createRulesEngine(rules) {
15270
15510
  }
15271
15511
 
15272
15512
  // ../core/dist/rules/config.js
15273
- var DEFAULT_INCLUDE_PATTERNS = [".vgc/**/*.yaml", ".vgc/**/*.yml", ".vgc/**/*.json"];
15513
+ var DEFAULT_INCLUDE_PATTERNS = [".principal-views/**/*.yaml", ".principal-views/**/*.yml", ".principal-views/**/*.json"];
15274
15514
  var DEFAULT_EXCLUDE_PATTERNS = ["**/node_modules/**", "**/*.test.*"];
15275
15515
  var VALID_SEVERITIES = [
15276
15516
  "off",
@@ -16189,7 +16429,7 @@ var noUnknownFields = {
16189
16429
  function checkFields(obj, allowedFields, path4, configPath, violations) {
16190
16430
  for (const field of Object.keys(obj)) {
16191
16431
  if (!allowedFields.includes(field)) {
16192
- const suggestion = findSimilarField(field, allowedFields);
16432
+ const suggestion = findSimilarField2(field, allowedFields);
16193
16433
  violations.push({
16194
16434
  ruleId: "no-unknown-fields",
16195
16435
  severity: "error",
@@ -16204,7 +16444,7 @@ function checkFields(obj, allowedFields, path4, configPath, violations) {
16204
16444
  }
16205
16445
  }
16206
16446
  }
16207
- function findSimilarField(field, allowedFields) {
16447
+ function findSimilarField2(field, allowedFields) {
16208
16448
  const fieldLower = field.toLowerCase();
16209
16449
  for (const allowed of allowedFields) {
16210
16450
  const allowedLower = allowed.toLowerCase();
@@ -16924,12 +17164,9 @@ function createDefaultRulesEngine() {
16924
17164
 
16925
17165
  // src/commands/lint.ts
16926
17166
  var CONFIG_FILE_NAMES2 = [
16927
- ".principal-viewsrc.json",
16928
- ".principal-viewsrc.yaml",
16929
- ".principal-viewsrc.yml",
16930
- "privu.config.json",
16931
- "privu.config.yaml",
16932
- "privu.config.yml"
17167
+ ".privurc.yaml",
17168
+ ".privurc.yml",
17169
+ ".privurc.json"
16933
17170
  ];
16934
17171
  function findConfig(startDir) {
16935
17172
  let currentDir = (0, import_node_path11.resolve)(startDir);
@@ -17142,7 +17379,7 @@ function createLintCommand() {
17142
17379
  });
17143
17380
  const configFiles = matchedFiles.filter((f) => {
17144
17381
  const name = (0, import_node_path11.basename)(f).toLowerCase();
17145
- return !name.startsWith("library.") && !name.startsWith(".principal-viewsrc") && !name.startsWith("privu.config");
17382
+ return !name.startsWith("library.") && !name.startsWith(".privurc");
17146
17383
  });
17147
17384
  if (configFiles.length === 0) {
17148
17385
  if (options.json) {