@principal-ai/principal-view-cli 0.1.18 → 0.1.20

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
@@ -13484,31 +13484,65 @@ function validateLibrary(library) {
13484
13484
  for (const [compId, compDef] of Object.entries(lib.nodeComponents)) {
13485
13485
  if (compDef && typeof compDef === "object") {
13486
13486
  const comp = compDef;
13487
- checkUnknownFields(comp, ALLOWED_LIBRARY_FIELDS.nodeComponent, `nodeComponents.${compId}`, issues);
13487
+ checkUnknownFields(
13488
+ comp,
13489
+ ALLOWED_LIBRARY_FIELDS.nodeComponent,
13490
+ `nodeComponents.${compId}`,
13491
+ issues
13492
+ );
13488
13493
  if (comp.size && typeof comp.size === "object") {
13489
- checkUnknownFields(comp.size, ALLOWED_LIBRARY_FIELDS.nodeComponentSize, `nodeComponents.${compId}.size`, issues);
13494
+ checkUnknownFields(
13495
+ comp.size,
13496
+ ALLOWED_LIBRARY_FIELDS.nodeComponentSize,
13497
+ `nodeComponents.${compId}.size`,
13498
+ issues
13499
+ );
13490
13500
  }
13491
13501
  if (comp.states && typeof comp.states === "object") {
13492
- for (const [stateId, stateDef] of Object.entries(comp.states)) {
13502
+ for (const [stateId, stateDef] of Object.entries(
13503
+ comp.states
13504
+ )) {
13493
13505
  if (stateDef && typeof stateDef === "object") {
13494
- checkUnknownFields(stateDef, ALLOWED_LIBRARY_FIELDS.nodeComponentState, `nodeComponents.${compId}.states.${stateId}`, issues);
13506
+ checkUnknownFields(
13507
+ stateDef,
13508
+ ALLOWED_LIBRARY_FIELDS.nodeComponentState,
13509
+ `nodeComponents.${compId}.states.${stateId}`,
13510
+ issues
13511
+ );
13495
13512
  }
13496
13513
  }
13497
13514
  }
13498
13515
  if (comp.dataSchema && typeof comp.dataSchema === "object") {
13499
- for (const [fieldName, fieldDef] of Object.entries(comp.dataSchema)) {
13516
+ for (const [fieldName, fieldDef] of Object.entries(
13517
+ comp.dataSchema
13518
+ )) {
13500
13519
  if (fieldDef && typeof fieldDef === "object") {
13501
- checkUnknownFields(fieldDef, ALLOWED_LIBRARY_FIELDS.nodeComponentDataSchemaField, `nodeComponents.${compId}.dataSchema.${fieldName}`, issues);
13520
+ checkUnknownFields(
13521
+ fieldDef,
13522
+ ALLOWED_LIBRARY_FIELDS.nodeComponentDataSchemaField,
13523
+ `nodeComponents.${compId}.dataSchema.${fieldName}`,
13524
+ issues
13525
+ );
13502
13526
  }
13503
13527
  }
13504
13528
  }
13505
13529
  if (comp.layout && typeof comp.layout === "object") {
13506
- checkUnknownFields(comp.layout, ALLOWED_LIBRARY_FIELDS.nodeComponentLayout, `nodeComponents.${compId}.layout`, issues);
13530
+ checkUnknownFields(
13531
+ comp.layout,
13532
+ ALLOWED_LIBRARY_FIELDS.nodeComponentLayout,
13533
+ `nodeComponents.${compId}.layout`,
13534
+ issues
13535
+ );
13507
13536
  }
13508
13537
  if (Array.isArray(comp.actions)) {
13509
13538
  comp.actions.forEach((action, actionIndex) => {
13510
13539
  if (action && typeof action === "object") {
13511
- checkUnknownFields(action, ALLOWED_LIBRARY_FIELDS.nodeComponentAction, `nodeComponents.${compId}.actions[${actionIndex}]`, issues);
13540
+ checkUnknownFields(
13541
+ action,
13542
+ ALLOWED_LIBRARY_FIELDS.nodeComponentAction,
13543
+ `nodeComponents.${compId}.actions[${actionIndex}]`,
13544
+ issues
13545
+ );
13512
13546
  }
13513
13547
  });
13514
13548
  }
@@ -13519,12 +13553,27 @@ function validateLibrary(library) {
13519
13553
  for (const [compId, compDef] of Object.entries(lib.edgeComponents)) {
13520
13554
  if (compDef && typeof compDef === "object") {
13521
13555
  const comp = compDef;
13522
- checkUnknownFields(comp, ALLOWED_LIBRARY_FIELDS.edgeComponent, `edgeComponents.${compId}`, issues);
13556
+ checkUnknownFields(
13557
+ comp,
13558
+ ALLOWED_LIBRARY_FIELDS.edgeComponent,
13559
+ `edgeComponents.${compId}`,
13560
+ issues
13561
+ );
13523
13562
  if (comp.animation && typeof comp.animation === "object") {
13524
- checkUnknownFields(comp.animation, ALLOWED_LIBRARY_FIELDS.edgeComponentAnimation, `edgeComponents.${compId}.animation`, issues);
13563
+ checkUnknownFields(
13564
+ comp.animation,
13565
+ ALLOWED_LIBRARY_FIELDS.edgeComponentAnimation,
13566
+ `edgeComponents.${compId}.animation`,
13567
+ issues
13568
+ );
13525
13569
  }
13526
13570
  if (comp.label && typeof comp.label === "object") {
13527
- checkUnknownFields(comp.label, ALLOWED_LIBRARY_FIELDS.edgeComponentLabel, `edgeComponents.${compId}.label`, issues);
13571
+ checkUnknownFields(
13572
+ comp.label,
13573
+ ALLOWED_LIBRARY_FIELDS.edgeComponentLabel,
13574
+ `edgeComponents.${compId}.label`,
13575
+ issues
13576
+ );
13528
13577
  }
13529
13578
  }
13530
13579
  }
@@ -13533,9 +13582,19 @@ function validateLibrary(library) {
13533
13582
  lib.connectionRules.forEach((rule, ruleIndex) => {
13534
13583
  if (rule && typeof rule === "object") {
13535
13584
  const r = rule;
13536
- checkUnknownFields(r, ALLOWED_LIBRARY_FIELDS.connectionRule, `connectionRules[${ruleIndex}]`, issues);
13585
+ checkUnknownFields(
13586
+ r,
13587
+ ALLOWED_LIBRARY_FIELDS.connectionRule,
13588
+ `connectionRules[${ruleIndex}]`,
13589
+ issues
13590
+ );
13537
13591
  if (r.constraints && typeof r.constraints === "object") {
13538
- checkUnknownFields(r.constraints, ALLOWED_LIBRARY_FIELDS.connectionRuleConstraints, `connectionRules[${ruleIndex}].constraints`, issues);
13592
+ checkUnknownFields(
13593
+ r.constraints,
13594
+ ALLOWED_LIBRARY_FIELDS.connectionRuleConstraints,
13595
+ `connectionRules[${ruleIndex}].constraints`,
13596
+ issues
13597
+ );
13539
13598
  }
13540
13599
  }
13541
13600
  });
@@ -13547,12 +13606,27 @@ var VALID_NODE_SHAPES = ["circle", "rectangle", "hexagon", "diamond", "custom"];
13547
13606
  var ALLOWED_CANVAS_FIELDS = {
13548
13607
  root: ["nodes", "edges", "pv"],
13549
13608
  pv: ["version", "name", "description", "nodeTypes", "edgeTypes", "pathConfig", "display"],
13550
- pvPathConfig: ["projectRoot", "captureSource", "enableActionPatterns", "logLevel", "ignoreUnsourced"],
13609
+ pvPathConfig: [
13610
+ "projectRoot",
13611
+ "captureSource",
13612
+ "enableActionPatterns",
13613
+ "logLevel",
13614
+ "ignoreUnsourced"
13615
+ ],
13551
13616
  pvDisplay: ["layout", "theme", "animations"],
13552
13617
  pvDisplayTheme: ["primary", "success", "warning", "danger", "info"],
13553
13618
  pvDisplayAnimations: ["enabled", "speed"],
13554
13619
  pvNodeType: ["label", "description", "color", "icon", "shape"],
13555
- pvEdgeType: ["label", "style", "color", "width", "directed", "animation", "labelConfig", "activatedBy"],
13620
+ pvEdgeType: [
13621
+ "label",
13622
+ "style",
13623
+ "color",
13624
+ "width",
13625
+ "directed",
13626
+ "animation",
13627
+ "labelConfig",
13628
+ "activatedBy"
13629
+ ],
13556
13630
  pvEdgeTypeAnimation: ["type", "duration", "color"],
13557
13631
  pvEdgeTypeLabelConfig: ["field", "position"],
13558
13632
  // Base node fields from JSON Canvas spec
@@ -13563,26 +13637,71 @@ var ALLOWED_CANVAS_FIELDS = {
13563
13637
  nodeLink: ["url"],
13564
13638
  nodeGroup: ["label", "background", "backgroundStyle"],
13565
13639
  // Node pv extension
13566
- nodePv: ["nodeType", "description", "shape", "icon", "fill", "stroke", "states", "sources", "actions", "dataSchema", "layout"],
13640
+ nodePv: [
13641
+ "nodeType",
13642
+ "description",
13643
+ "shape",
13644
+ "icon",
13645
+ "fill",
13646
+ "stroke",
13647
+ "states",
13648
+ "sources",
13649
+ "actions",
13650
+ "dataSchema",
13651
+ "layout"
13652
+ ],
13567
13653
  nodePvState: ["color", "icon", "label"],
13568
13654
  nodePvAction: ["pattern", "event", "state", "metadata", "triggerEdges"],
13569
13655
  nodePvDataSchemaField: ["type", "required", "displayInLabel"],
13570
13656
  nodePvLayout: ["layer", "cluster"],
13571
13657
  // Edge fields
13572
- edge: ["id", "fromNode", "toNode", "fromSide", "toSide", "fromEnd", "toEnd", "color", "label", "pv"],
13658
+ edge: [
13659
+ "id",
13660
+ "fromNode",
13661
+ "toNode",
13662
+ "fromSide",
13663
+ "toSide",
13664
+ "fromEnd",
13665
+ "toEnd",
13666
+ "color",
13667
+ "label",
13668
+ "pv"
13669
+ ],
13573
13670
  edgePv: ["edgeType", "style", "width", "animation", "activatedBy"],
13574
13671
  edgePvAnimation: ["type", "duration", "color"],
13575
13672
  edgePvActivatedBy: ["action", "animation", "direction", "duration"]
13576
13673
  };
13577
13674
  var ALLOWED_LIBRARY_FIELDS = {
13578
13675
  root: ["version", "name", "description", "nodeComponents", "edgeComponents", "connectionRules"],
13579
- nodeComponent: ["description", "tags", "defaultLabel", "shape", "icon", "color", "size", "states", "sources", "actions", "dataSchema", "layout"],
13676
+ nodeComponent: [
13677
+ "description",
13678
+ "tags",
13679
+ "defaultLabel",
13680
+ "shape",
13681
+ "icon",
13682
+ "color",
13683
+ "size",
13684
+ "states",
13685
+ "sources",
13686
+ "actions",
13687
+ "dataSchema",
13688
+ "layout"
13689
+ ],
13580
13690
  nodeComponentSize: ["width", "height"],
13581
13691
  nodeComponentState: ["color", "icon", "label"],
13582
13692
  nodeComponentAction: ["pattern", "event", "state", "metadata", "triggerEdges"],
13583
13693
  nodeComponentDataSchemaField: ["type", "required", "displayInLabel", "label", "displayInInfo"],
13584
13694
  nodeComponentLayout: ["layer", "cluster"],
13585
- edgeComponent: ["description", "tags", "style", "color", "width", "directed", "animation", "label"],
13695
+ edgeComponent: [
13696
+ "description",
13697
+ "tags",
13698
+ "style",
13699
+ "color",
13700
+ "width",
13701
+ "directed",
13702
+ "animation",
13703
+ "label"
13704
+ ],
13586
13705
  edgeComponentAnimation: ["type", "duration", "color"],
13587
13706
  edgeComponentLabel: ["field", "position"],
13588
13707
  connectionRule: ["from", "to", "via", "constraints"],
@@ -13661,23 +13780,43 @@ function validateCanvas(canvas, filePath, library) {
13661
13780
  });
13662
13781
  }
13663
13782
  if (pv.pathConfig && typeof pv.pathConfig === "object") {
13664
- checkUnknownFields(pv.pathConfig, ALLOWED_CANVAS_FIELDS.pvPathConfig, "pv.pathConfig", issues);
13783
+ checkUnknownFields(
13784
+ pv.pathConfig,
13785
+ ALLOWED_CANVAS_FIELDS.pvPathConfig,
13786
+ "pv.pathConfig",
13787
+ issues
13788
+ );
13665
13789
  }
13666
13790
  if (pv.display && typeof pv.display === "object") {
13667
13791
  const display = pv.display;
13668
13792
  checkUnknownFields(display, ALLOWED_CANVAS_FIELDS.pvDisplay, "pv.display", issues);
13669
13793
  if (display.theme && typeof display.theme === "object") {
13670
- checkUnknownFields(display.theme, ALLOWED_CANVAS_FIELDS.pvDisplayTheme, "pv.display.theme", issues);
13794
+ checkUnknownFields(
13795
+ display.theme,
13796
+ ALLOWED_CANVAS_FIELDS.pvDisplayTheme,
13797
+ "pv.display.theme",
13798
+ issues
13799
+ );
13671
13800
  }
13672
13801
  if (display.animations && typeof display.animations === "object") {
13673
- checkUnknownFields(display.animations, ALLOWED_CANVAS_FIELDS.pvDisplayAnimations, "pv.display.animations", issues);
13802
+ checkUnknownFields(
13803
+ display.animations,
13804
+ ALLOWED_CANVAS_FIELDS.pvDisplayAnimations,
13805
+ "pv.display.animations",
13806
+ issues
13807
+ );
13674
13808
  }
13675
13809
  }
13676
13810
  if (pv.nodeTypes && typeof pv.nodeTypes === "object") {
13677
13811
  canvasNodeTypes = Object.keys(pv.nodeTypes);
13678
13812
  for (const [typeId, typeDef] of Object.entries(pv.nodeTypes)) {
13679
13813
  if (typeDef && typeof typeDef === "object") {
13680
- checkUnknownFields(typeDef, ALLOWED_CANVAS_FIELDS.pvNodeType, `pv.nodeTypes.${typeId}`, issues);
13814
+ checkUnknownFields(
13815
+ typeDef,
13816
+ ALLOWED_CANVAS_FIELDS.pvNodeType,
13817
+ `pv.nodeTypes.${typeId}`,
13818
+ issues
13819
+ );
13681
13820
  }
13682
13821
  }
13683
13822
  }
@@ -13686,12 +13825,27 @@ function validateCanvas(canvas, filePath, library) {
13686
13825
  for (const [typeId, typeDef] of Object.entries(pv.edgeTypes)) {
13687
13826
  if (typeDef && typeof typeDef === "object") {
13688
13827
  const edgeTypeDef = typeDef;
13689
- checkUnknownFields(edgeTypeDef, ALLOWED_CANVAS_FIELDS.pvEdgeType, `pv.edgeTypes.${typeId}`, issues);
13828
+ checkUnknownFields(
13829
+ edgeTypeDef,
13830
+ ALLOWED_CANVAS_FIELDS.pvEdgeType,
13831
+ `pv.edgeTypes.${typeId}`,
13832
+ issues
13833
+ );
13690
13834
  if (edgeTypeDef.animation && typeof edgeTypeDef.animation === "object") {
13691
- checkUnknownFields(edgeTypeDef.animation, ALLOWED_CANVAS_FIELDS.pvEdgeTypeAnimation, `pv.edgeTypes.${typeId}.animation`, issues);
13835
+ checkUnknownFields(
13836
+ edgeTypeDef.animation,
13837
+ ALLOWED_CANVAS_FIELDS.pvEdgeTypeAnimation,
13838
+ `pv.edgeTypes.${typeId}.animation`,
13839
+ issues
13840
+ );
13692
13841
  }
13693
13842
  if (edgeTypeDef.labelConfig && typeof edgeTypeDef.labelConfig === "object") {
13694
- checkUnknownFields(edgeTypeDef.labelConfig, ALLOWED_CANVAS_FIELDS.pvEdgeTypeLabelConfig, `pv.edgeTypes.${typeId}.labelConfig`, issues);
13843
+ checkUnknownFields(
13844
+ edgeTypeDef.labelConfig,
13845
+ ALLOWED_CANVAS_FIELDS.pvEdgeTypeLabelConfig,
13846
+ `pv.edgeTypes.${typeId}.labelConfig`,
13847
+ issues
13848
+ );
13695
13849
  }
13696
13850
  }
13697
13851
  }
@@ -13704,7 +13858,11 @@ function validateCanvas(canvas, filePath, library) {
13704
13858
  } else {
13705
13859
  c.nodes.forEach((node, index) => {
13706
13860
  if (!node || typeof node !== "object") {
13707
- issues.push({ type: "error", message: `Node at index ${index} must be an object`, path: `nodes[${index}]` });
13861
+ issues.push({
13862
+ type: "error",
13863
+ message: `Node at index ${index} must be an object`,
13864
+ path: `nodes[${index}]`
13865
+ });
13708
13866
  return;
13709
13867
  }
13710
13868
  const n = node;
@@ -13723,31 +13881,83 @@ function validateCanvas(canvas, filePath, library) {
13723
13881
  }
13724
13882
  checkUnknownFields(n, allowedNodeFields, nodePath2, issues);
13725
13883
  if (typeof n.id !== "string" || !n.id) {
13726
- issues.push({ type: "error", message: `Node at index ${index} must have a string "id"`, path: `${nodePath2}.id` });
13884
+ issues.push({
13885
+ type: "error",
13886
+ message: `Node at index ${index} must have a string "id"`,
13887
+ path: `${nodePath2}.id`
13888
+ });
13727
13889
  }
13728
13890
  if (typeof n.type !== "string") {
13729
- issues.push({ type: "error", message: `Node "${nodeLabel}" must have a string "type"`, path: `${nodePath2}.type` });
13891
+ issues.push({
13892
+ type: "error",
13893
+ message: `Node "${nodeLabel}" must have a string "type"`,
13894
+ path: `${nodePath2}.type`
13895
+ });
13730
13896
  }
13731
13897
  if (typeof n.x !== "number") {
13732
- issues.push({ type: "error", message: `Node "${nodeLabel}" must have a numeric "x" position`, path: `${nodePath2}.x` });
13898
+ issues.push({
13899
+ type: "error",
13900
+ message: `Node "${nodeLabel}" must have a numeric "x" position`,
13901
+ path: `${nodePath2}.x`
13902
+ });
13733
13903
  }
13734
13904
  if (typeof n.y !== "number") {
13735
- issues.push({ type: "error", message: `Node "${nodeLabel}" must have a numeric "y" position`, path: `${nodePath2}.y` });
13905
+ issues.push({
13906
+ type: "error",
13907
+ message: `Node "${nodeLabel}" must have a numeric "y" position`,
13908
+ path: `${nodePath2}.y`
13909
+ });
13736
13910
  }
13737
13911
  if (typeof n.width !== "number") {
13738
- issues.push({ type: "error", message: `Node "${nodeLabel}" must have a numeric "width"`, path: `${nodePath2}.width` });
13912
+ issues.push({
13913
+ type: "error",
13914
+ message: `Node "${nodeLabel}" must have a numeric "width"`,
13915
+ path: `${nodePath2}.width`
13916
+ });
13739
13917
  }
13740
13918
  if (typeof n.height !== "number") {
13741
- issues.push({ type: "error", message: `Node "${nodeLabel}" must have a numeric "height"`, path: `${nodePath2}.height` });
13919
+ issues.push({
13920
+ type: "error",
13921
+ message: `Node "${nodeLabel}" must have a numeric "height"`,
13922
+ path: `${nodePath2}.height`
13923
+ });
13924
+ }
13925
+ if (nodeType === "text" && (typeof n.text !== "string" || !n.text)) {
13926
+ issues.push({
13927
+ type: "error",
13928
+ message: `Node "${nodeLabel}" has type "text" but is missing required "text" field`,
13929
+ path: `${nodePath2}.text`,
13930
+ suggestion: 'Add a "text" field with markdown content, or change the node type'
13931
+ });
13742
13932
  }
13743
- const isStandardType = STANDARD_CANVAS_TYPES.includes(nodeType);
13933
+ if (nodeType === "file" && (typeof n.file !== "string" || !n.file)) {
13934
+ issues.push({
13935
+ type: "error",
13936
+ message: `Node "${nodeLabel}" has type "file" but is missing required "file" field`,
13937
+ path: `${nodePath2}.file`,
13938
+ suggestion: 'Add a "file" field with a file path, or change the node type'
13939
+ });
13940
+ }
13941
+ if (nodeType === "link" && (typeof n.url !== "string" || !n.url)) {
13942
+ issues.push({
13943
+ type: "error",
13944
+ message: `Node "${nodeLabel}" has type "link" but is missing required "url" field`,
13945
+ path: `${nodePath2}.url`,
13946
+ suggestion: 'Add a "url" field with a URL, or change the node type'
13947
+ });
13948
+ }
13949
+ const isStandardType = STANDARD_CANVAS_TYPES.includes(
13950
+ nodeType
13951
+ );
13744
13952
  if (!isStandardType) {
13745
13953
  if (!n.pv || typeof n.pv !== "object") {
13746
13954
  issues.push({
13747
13955
  type: "error",
13748
13956
  message: `Node "${n.id || index}" uses custom type "${nodeType}" but has no "pv" extension`,
13749
13957
  path: `nodes[${index}].pv`,
13750
- suggestion: `Use a standard type (${STANDARD_CANVAS_TYPES.join(", ")}) or add pv.nodeType and pv.shape`
13958
+ suggestion: `Use a standard type (${STANDARD_CANVAS_TYPES.join(
13959
+ ", "
13960
+ )}) or add pv.nodeType and pv.shape`
13751
13961
  });
13752
13962
  } else {
13753
13963
  const nodePv = n.pv;
@@ -13772,26 +13982,50 @@ function validateCanvas(canvas, filePath, library) {
13772
13982
  const nodePv = n.pv;
13773
13983
  checkUnknownFields(nodePv, ALLOWED_CANVAS_FIELDS.nodePv, `${nodePath2}.pv`, issues);
13774
13984
  if (nodePv.states && typeof nodePv.states === "object") {
13775
- for (const [stateId, stateDef] of Object.entries(nodePv.states)) {
13985
+ for (const [stateId, stateDef] of Object.entries(
13986
+ nodePv.states
13987
+ )) {
13776
13988
  if (stateDef && typeof stateDef === "object") {
13777
- checkUnknownFields(stateDef, ALLOWED_CANVAS_FIELDS.nodePvState, `${nodePath2}.pv.states.${stateId}`, issues);
13989
+ checkUnknownFields(
13990
+ stateDef,
13991
+ ALLOWED_CANVAS_FIELDS.nodePvState,
13992
+ `${nodePath2}.pv.states.${stateId}`,
13993
+ issues
13994
+ );
13778
13995
  }
13779
13996
  }
13780
13997
  }
13781
13998
  if (nodePv.dataSchema && typeof nodePv.dataSchema === "object") {
13782
- for (const [fieldName, fieldDef] of Object.entries(nodePv.dataSchema)) {
13999
+ for (const [fieldName, fieldDef] of Object.entries(
14000
+ nodePv.dataSchema
14001
+ )) {
13783
14002
  if (fieldDef && typeof fieldDef === "object") {
13784
- checkUnknownFields(fieldDef, ALLOWED_CANVAS_FIELDS.nodePvDataSchemaField, `${nodePath2}.pv.dataSchema.${fieldName}`, issues);
14003
+ checkUnknownFields(
14004
+ fieldDef,
14005
+ ALLOWED_CANVAS_FIELDS.nodePvDataSchemaField,
14006
+ `${nodePath2}.pv.dataSchema.${fieldName}`,
14007
+ issues
14008
+ );
13785
14009
  }
13786
14010
  }
13787
14011
  }
13788
14012
  if (nodePv.layout && typeof nodePv.layout === "object") {
13789
- checkUnknownFields(nodePv.layout, ALLOWED_CANVAS_FIELDS.nodePvLayout, `${nodePath2}.pv.layout`, issues);
14013
+ checkUnknownFields(
14014
+ nodePv.layout,
14015
+ ALLOWED_CANVAS_FIELDS.nodePvLayout,
14016
+ `${nodePath2}.pv.layout`,
14017
+ issues
14018
+ );
13790
14019
  }
13791
14020
  if (Array.isArray(nodePv.actions)) {
13792
14021
  nodePv.actions.forEach((action, actionIndex) => {
13793
14022
  if (action && typeof action === "object") {
13794
- checkUnknownFields(action, ALLOWED_CANVAS_FIELDS.nodePvAction, `${nodePath2}.pv.actions[${actionIndex}]`, issues);
14023
+ checkUnknownFields(
14024
+ action,
14025
+ ALLOWED_CANVAS_FIELDS.nodePvAction,
14026
+ `${nodePath2}.pv.actions[${actionIndex}]`,
14027
+ issues
14028
+ );
13795
14029
  }
13796
14030
  });
13797
14031
  }
@@ -13829,7 +14063,11 @@ function validateCanvas(canvas, filePath, library) {
13829
14063
  const nodeIds = new Set(c.nodes?.map((n) => n.id) || []);
13830
14064
  c.edges.forEach((edge, index) => {
13831
14065
  if (!edge || typeof edge !== "object") {
13832
- issues.push({ type: "error", message: `Edge at index ${index} must be an object`, path: `edges[${index}]` });
14066
+ issues.push({
14067
+ type: "error",
14068
+ message: `Edge at index ${index} must be an object`,
14069
+ path: `edges[${index}]`
14070
+ });
13833
14071
  return;
13834
14072
  }
13835
14073
  const e = edge;
@@ -13837,28 +14075,58 @@ function validateCanvas(canvas, filePath, library) {
13837
14075
  const edgeLabel = e.id || index;
13838
14076
  checkUnknownFields(e, ALLOWED_CANVAS_FIELDS.edge, edgePath, issues);
13839
14077
  if (typeof e.id !== "string" || !e.id) {
13840
- issues.push({ type: "error", message: `Edge at index ${index} must have a string "id"`, path: `${edgePath}.id` });
14078
+ issues.push({
14079
+ type: "error",
14080
+ message: `Edge at index ${index} must have a string "id"`,
14081
+ path: `${edgePath}.id`
14082
+ });
13841
14083
  }
13842
14084
  if (typeof e.fromNode !== "string") {
13843
- issues.push({ type: "error", message: `Edge "${edgeLabel}" must have a string "fromNode"`, path: `${edgePath}.fromNode` });
14085
+ issues.push({
14086
+ type: "error",
14087
+ message: `Edge "${edgeLabel}" must have a string "fromNode"`,
14088
+ path: `${edgePath}.fromNode`
14089
+ });
13844
14090
  } else if (!nodeIds.has(e.fromNode)) {
13845
- issues.push({ type: "error", message: `Edge "${edgeLabel}" references unknown node "${e.fromNode}"`, path: `${edgePath}.fromNode` });
14091
+ issues.push({
14092
+ type: "error",
14093
+ message: `Edge "${edgeLabel}" references unknown node "${e.fromNode}"`,
14094
+ path: `${edgePath}.fromNode`
14095
+ });
13846
14096
  }
13847
14097
  if (typeof e.toNode !== "string") {
13848
- issues.push({ type: "error", message: `Edge "${edgeLabel}" must have a string "toNode"`, path: `${edgePath}.toNode` });
14098
+ issues.push({
14099
+ type: "error",
14100
+ message: `Edge "${edgeLabel}" must have a string "toNode"`,
14101
+ path: `${edgePath}.toNode`
14102
+ });
13849
14103
  } else if (!nodeIds.has(e.toNode)) {
13850
- issues.push({ type: "error", message: `Edge "${edgeLabel}" references unknown node "${e.toNode}"`, path: `${edgePath}.toNode` });
14104
+ issues.push({
14105
+ type: "error",
14106
+ message: `Edge "${edgeLabel}" references unknown node "${e.toNode}"`,
14107
+ path: `${edgePath}.toNode`
14108
+ });
13851
14109
  }
13852
14110
  if (e.pv && typeof e.pv === "object") {
13853
14111
  const edgePv = e.pv;
13854
14112
  checkUnknownFields(edgePv, ALLOWED_CANVAS_FIELDS.edgePv, `${edgePath}.pv`, issues);
13855
14113
  if (edgePv.animation && typeof edgePv.animation === "object") {
13856
- checkUnknownFields(edgePv.animation, ALLOWED_CANVAS_FIELDS.edgePvAnimation, `${edgePath}.pv.animation`, issues);
14114
+ checkUnknownFields(
14115
+ edgePv.animation,
14116
+ ALLOWED_CANVAS_FIELDS.edgePvAnimation,
14117
+ `${edgePath}.pv.animation`,
14118
+ issues
14119
+ );
13857
14120
  }
13858
14121
  if (Array.isArray(edgePv.activatedBy)) {
13859
14122
  edgePv.activatedBy.forEach((trigger, triggerIndex) => {
13860
14123
  if (trigger && typeof trigger === "object") {
13861
- checkUnknownFields(trigger, ALLOWED_CANVAS_FIELDS.edgePvActivatedBy, `${edgePath}.pv.activatedBy[${triggerIndex}]`, issues);
14124
+ checkUnknownFields(
14125
+ trigger,
14126
+ ALLOWED_CANVAS_FIELDS.edgePvActivatedBy,
14127
+ `${edgePath}.pv.activatedBy[${triggerIndex}]`,
14128
+ issues
14129
+ );
13862
14130
  }
13863
14131
  });
13864
14132
  }
@@ -13923,7 +14191,10 @@ function validateFile(filePath, library) {
13923
14191
  }
13924
14192
  function createValidateCommand() {
13925
14193
  const command = new Command("validate");
13926
- command.description("Validate .canvas configuration files").argument("[files...]", "Files or glob patterns to validate (defaults to .principal-views/*.canvas)").option("-q, --quiet", "Only output errors").option("--json", "Output results as JSON").action(async (files, options) => {
14194
+ command.description("Validate .canvas configuration files").argument(
14195
+ "[files...]",
14196
+ "Files or glob patterns to validate (defaults to .principal-views/*.canvas)"
14197
+ ).option("-q, --quiet", "Only output errors").option("--json", "Output results as JSON").action(async (files, options) => {
13927
14198
  try {
13928
14199
  const patterns = files.length > 0 ? files : [".principal-views/*.canvas"];
13929
14200
  const matchedFiles = await globby(patterns, {
@@ -13956,10 +14227,16 @@ function createValidateCommand() {
13956
14227
  const validCount = allResults.filter((r) => r.isValid).length;
13957
14228
  const invalidCount = allResults.length - validCount;
13958
14229
  if (options.json) {
13959
- console.log(JSON.stringify({
13960
- files: allResults,
13961
- summary: { total: allResults.length, valid: validCount, invalid: invalidCount }
13962
- }, null, 2));
14230
+ console.log(
14231
+ JSON.stringify(
14232
+ {
14233
+ files: allResults,
14234
+ summary: { total: allResults.length, valid: validCount, invalid: invalidCount }
14235
+ },
14236
+ null,
14237
+ 2
14238
+ )
14239
+ );
13963
14240
  } else {
13964
14241
  if (!options.quiet) {
13965
14242
  const fileCount = libraryResult ? `${results.length} canvas file(s) + library` : `${results.length} canvas file(s)`;
@@ -13994,7 +14271,9 @@ Validating ${fileCount}...
13994
14271
  if (invalidCount === 0) {
13995
14272
  console.log(source_default.green(`\u2713 All ${validCount} file(s) are valid`));
13996
14273
  } else {
13997
- console.log(source_default.red(`\u2717 ${invalidCount} of ${allResults.length} file(s) failed validation`));
14274
+ console.log(
14275
+ source_default.red(`\u2717 ${invalidCount} of ${allResults.length} file(s) failed validation`)
14276
+ );
13998
14277
  process.exit(1);
13999
14278
  }
14000
14279
  }
@@ -14109,7 +14388,9 @@ function createInitCommand() {
14109
14388
  console.log(source_default.green(`Created directory: .principal-views/`));
14110
14389
  }
14111
14390
  if ((0, import_node_fs5.existsSync)(canvasFile) && !options.force) {
14112
- console.log(source_default.yellow(`Canvas file already exists: .principal-views/${options.name}.canvas`));
14391
+ console.log(
14392
+ source_default.yellow(`Canvas file already exists: .principal-views/${options.name}.canvas`)
14393
+ );
14113
14394
  } else {
14114
14395
  (0, import_node_fs5.writeFileSync)(canvasFile, JSON.stringify(TEMPLATE_CANVAS, null, 2));
14115
14396
  console.log(source_default.green(`Created canvas file: .principal-views/${options.name}.canvas`));
@@ -14150,11 +14431,15 @@ edgeComponents: {}
14150
14431
  if ((0, import_node_fs5.existsSync)(preCommitFile)) {
14151
14432
  const existingContent = (0, import_node_fs5.readFileSync)(preCommitFile, "utf8");
14152
14433
  if (existingContent.includes("principal-view-cli lint") || existingContent.includes("privu lint")) {
14153
- console.log(source_default.yellow(`Husky pre-commit hook already includes principal view linting`));
14434
+ console.log(
14435
+ source_default.yellow(`Husky pre-commit hook already includes principal view linting`)
14436
+ );
14154
14437
  } else {
14155
14438
  const updatedContent = existingContent.trimEnd() + "\n\n# Run principal view linting\nnpx @principal-ai/principal-view-cli lint --quiet\n";
14156
14439
  (0, import_node_fs5.writeFileSync)(preCommitFile, updatedContent);
14157
- console.log(source_default.green(`Updated Husky pre-commit hook with principal view linting`));
14440
+ console.log(
14441
+ source_default.green(`Updated Husky pre-commit hook with principal view linting`)
14442
+ );
14158
14443
  huskySetup = true;
14159
14444
  }
14160
14445
  } else {
@@ -14184,8 +14469,16 @@ edgeComponents: {}
14184
14469
  console.log(source_default.green(`Installed Husky and created pre-commit hook`));
14185
14470
  huskySetup = true;
14186
14471
  } catch (installError) {
14187
- console.log(source_default.yellow(`Could not install Husky automatically: ${installError.message}`));
14188
- console.log(source_default.dim(` You can install it manually: ${pm} add --dev husky && npx husky init`));
14472
+ console.log(
14473
+ source_default.yellow(
14474
+ `Could not install Husky automatically: ${installError.message}`
14475
+ )
14476
+ );
14477
+ console.log(
14478
+ source_default.dim(
14479
+ ` You can install it manually: ${pm} add --dev husky && npx husky init`
14480
+ )
14481
+ );
14189
14482
  }
14190
14483
  }
14191
14484
  }
@@ -14196,8 +14489,12 @@ edgeComponents: {}
14196
14489
  console.log(source_default.bold("Setup complete!"));
14197
14490
  console.log("");
14198
14491
  console.log(source_default.bold("Files created:"));
14199
- console.log(` \u2022 ${source_default.cyan(".principal-views/library.yaml")} - Component library definitions`);
14200
- console.log(` \u2022 ${source_default.cyan(`.principal-views/${options.name}.canvas`)} - Graph canvas file`);
14492
+ console.log(
14493
+ ` \u2022 ${source_default.cyan(".principal-views/library.yaml")} - Component library definitions`
14494
+ );
14495
+ console.log(
14496
+ ` \u2022 ${source_default.cyan(`.principal-views/${options.name}.canvas`)} - Graph canvas file`
14497
+ );
14201
14498
  if (options.lintConfig !== false) {
14202
14499
  console.log(` \u2022 ${source_default.cyan(".privurc.yaml")} - Lint configuration`);
14203
14500
  }
@@ -14207,7 +14504,9 @@ edgeComponents: {}
14207
14504
  console.log("");
14208
14505
  console.log(source_default.bold("Next steps:"));
14209
14506
  console.log(` 1. Define components in ${source_default.cyan(".principal-views/library.yaml")}`);
14210
- console.log(` 2. Build your graph in ${source_default.cyan(`.principal-views/${options.name}.canvas`)}`);
14507
+ console.log(
14508
+ ` 2. Build your graph in ${source_default.cyan(`.principal-views/${options.name}.canvas`)}`
14509
+ );
14211
14510
  console.log(` 3. Run ${source_default.cyan("privu lint")} to validate your configuration`);
14212
14511
  if (huskySetup) {
14213
14512
  console.log(` 4. Commits will now automatically lint .principal-views files`);
@@ -14303,11 +14602,21 @@ with standard canvas tools like Obsidian.
14303
14602
  ${source_default.bold("Required Structure:")}
14304
14603
  ${source_default.dim("\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510")}
14305
14604
  ${source_default.dim("\u2502")} { ${source_default.dim("\u2502")}
14306
- ${source_default.dim("\u2502")} ${source_default.green('"nodes"')}: [...], ${source_default.dim("// Required: array of nodes")} ${source_default.dim("\u2502")}
14307
- ${source_default.dim("\u2502")} ${source_default.green('"edges"')}: [...], ${source_default.dim("// Optional: array of edges")} ${source_default.dim("\u2502")}
14308
- ${source_default.dim("\u2502")} ${source_default.green('"pv"')}: { ${source_default.dim("// Required: PV extension")} ${source_default.dim("\u2502")}
14309
- ${source_default.dim("\u2502")} ${source_default.yellow('"name"')}: "...", ${source_default.dim("// Required: graph name")} ${source_default.dim("\u2502")}
14310
- ${source_default.dim("\u2502")} ${source_default.yellow('"version"')}: "..." ${source_default.dim("// Required: schema version")} ${source_default.dim("\u2502")}
14605
+ ${source_default.dim("\u2502")} ${source_default.green('"nodes"')}: [...], ${source_default.dim(
14606
+ "// Required: array of nodes"
14607
+ )} ${source_default.dim("\u2502")}
14608
+ ${source_default.dim("\u2502")} ${source_default.green('"edges"')}: [...], ${source_default.dim(
14609
+ "// Optional: array of edges"
14610
+ )} ${source_default.dim("\u2502")}
14611
+ ${source_default.dim("\u2502")} ${source_default.green('"pv"')}: { ${source_default.dim(
14612
+ "// Required: PV extension"
14613
+ )} ${source_default.dim("\u2502")}
14614
+ ${source_default.dim("\u2502")} ${source_default.yellow('"name"')}: "...", ${source_default.dim(
14615
+ "// Required: graph name"
14616
+ )} ${source_default.dim("\u2502")}
14617
+ ${source_default.dim("\u2502")} ${source_default.yellow('"version"')}: "..." ${source_default.dim(
14618
+ "// Required: schema version"
14619
+ )} ${source_default.dim("\u2502")}
14311
14620
  ${source_default.dim("\u2502")} } ${source_default.dim("\u2502")}
14312
14621
  ${source_default.dim("\u2502")} } ${source_default.dim("\u2502")}
14313
14622
  ${source_default.dim("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518")}
@@ -14338,7 +14647,9 @@ ${source_default.bold("Standard Node Types:")}
14338
14647
  Requires: ${source_default.dim("text")} (string)
14339
14648
 
14340
14649
  ${source_default.yellow("group")} Visual container for other nodes
14341
- Optional: ${source_default.dim("label")}, ${source_default.dim("background")}, ${source_default.dim("backgroundStyle")}
14650
+ Optional: ${source_default.dim("label")}, ${source_default.dim("background")}, ${source_default.dim(
14651
+ "backgroundStyle"
14652
+ )}
14342
14653
 
14343
14654
  ${source_default.yellow("file")} Reference to external file
14344
14655
  Requires: ${source_default.dim("file")} (path string)
@@ -14409,7 +14720,9 @@ ${source_default.bold("Defining Edge Types (in canvas vv):")}
14409
14720
  "version": "1.0.0",
14410
14721
  ${source_default.yellow('"edgeTypes"')}: {
14411
14722
  "query": {
14412
- ${source_default.cyan('"style"')}: "solid", ${source_default.dim("// solid, dashed, dotted, animated")}
14723
+ ${source_default.cyan('"style"')}: "solid", ${source_default.dim(
14724
+ "// solid, dashed, dotted, animated"
14725
+ )}
14413
14726
  ${source_default.cyan('"color"')}: "#64748b", ${source_default.dim("// Hex color")}
14414
14727
  ${source_default.cyan('"width"')}: 2, ${source_default.dim("// Line width in pixels")}
14415
14728
  ${source_default.cyan('"directed"')}: true, ${source_default.dim("// Show arrow")}
@@ -14463,7 +14776,9 @@ ${source_default.bold("Node-Level pv (for custom types):")}
14463
14776
  ${source_default.yellow('"nodeType"')}: "service", ${source_default.dim("// Required: Type identifier")}
14464
14777
  ${source_default.yellow('"shape"')}: "rectangle", ${source_default.dim("// Required: Visual shape")}
14465
14778
  ${source_default.cyan('"fill"')}: "#3b82f6", ${source_default.dim("// Optional: Fill color (hex)")}
14466
- ${source_default.cyan('"stroke"')}: "#1d4ed8", ${source_default.dim("// Optional: Border color (hex)")}
14779
+ ${source_default.cyan('"stroke"')}: "#1d4ed8", ${source_default.dim(
14780
+ "// Optional: Border color (hex)"
14781
+ )}
14467
14782
  ${source_default.cyan('"icon"')}: "Server", ${source_default.dim("// Optional: Lucide icon name")}
14468
14783
  ${source_default.cyan('"sources"')}: ["src/**/*.ts"], ${source_default.dim("// Optional: Source patterns")}
14469
14784
  ${source_default.cyan('"states"')}: { ${source_default.dim("// Optional: State definitions")}
@@ -14705,7 +15020,9 @@ async function checkConfig(configPath, projectRoot) {
14705
15020
  type: "warning",
14706
15021
  configFile: relativePath,
14707
15022
  nodeType: nodeTypeName,
14708
- message: `Config may be stale: "${newestFile}" was modified ${formatTimeDiff(timeDiff)} after the config`,
15023
+ message: `Config may be stale: "${newestFile}" was modified ${formatTimeDiff(
15024
+ timeDiff
15025
+ )} after the config`,
14709
15026
  details: `Pattern: ${pattern} (matched ${matchedFiles.length} file${matchedFiles.length > 1 ? "s" : ""})`
14710
15027
  });
14711
15028
  }
@@ -14729,7 +15046,9 @@ function createDoctorCommand() {
14729
15046
  const vgcDir = (0, import_node_path8.resolve)(projectRoot, ".principal-views");
14730
15047
  if (!(0, import_node_fs7.existsSync)(vgcDir)) {
14731
15048
  if (options.json) {
14732
- console.log(JSON.stringify({ error: "No .principal-views directory found", results: [] }));
15049
+ console.log(
15050
+ JSON.stringify({ error: "No .principal-views directory found", results: [] })
15051
+ );
14733
15052
  } else {
14734
15053
  console.log(source_default.yellow("No .principal-views directory found."));
14735
15054
  console.log(source_default.dim('Run "privu init" to create a configuration.'));
@@ -14743,7 +15062,9 @@ function createDoctorCommand() {
14743
15062
  });
14744
15063
  if (configFiles.length === 0) {
14745
15064
  if (options.json) {
14746
- console.log(JSON.stringify({ error: "No config files found in .principal-views", results: [] }));
15065
+ console.log(
15066
+ JSON.stringify({ error: "No config files found in .principal-views", results: [] })
15067
+ );
14747
15068
  } else {
14748
15069
  console.log(source_default.yellow("No configuration files found in .principal-views/"));
14749
15070
  }
@@ -14803,7 +15124,9 @@ Checking ${results.length} configuration file(s)...
14803
15124
  for (const result of results) {
14804
15125
  const issues = filterIssues(result.issues);
14805
15126
  if (issues.length === 0 && !options.quiet && !options.errorsOnly) {
14806
- console.log(source_default.green(`\u2713 ${result.configFile}`) + source_default.dim(` (${result.configName})`));
15127
+ console.log(
15128
+ source_default.green(`\u2713 ${result.configFile}`) + source_default.dim(` (${result.configName})`)
15129
+ );
14807
15130
  continue;
14808
15131
  }
14809
15132
  if (issues.length > 0) {
@@ -14923,7 +15246,9 @@ function initializeHusky(repoPath) {
14923
15246
  }
14924
15247
  console.log("\u2705 Husky installed and initialized");
14925
15248
  } catch (error) {
14926
- throw new Error(`Failed to initialize husky: ${error instanceof Error ? error.message : String(error)}`);
15249
+ throw new Error(
15250
+ `Failed to initialize husky: ${error instanceof Error ? error.message : String(error)}`
15251
+ );
14927
15252
  }
14928
15253
  }
14929
15254
  }
@@ -15055,7 +15380,9 @@ function createHooksCommand() {
15055
15380
  console.log(source_default.bold("\nPrincipal View Hooks Status\n"));
15056
15381
  console.log(`Repository: ${repoPath}`);
15057
15382
  console.log(`Husky: ${source_default.green("installed")}`);
15058
- console.log(`PV Hooks: ${hasHook ? source_default.green("configured") : source_default.yellow("not configured")}`);
15383
+ console.log(
15384
+ `PV Hooks: ${hasHook ? source_default.green("configured") : source_default.yellow("not configured")}`
15385
+ );
15059
15386
  if (hasHook) {
15060
15387
  console.log("\nUse --remove to remove or --check to verify");
15061
15388
  } else {
@@ -15079,7 +15406,10 @@ var TEMPLATE_CANVAS2 = {
15079
15406
  };
15080
15407
  function createCreateCommand() {
15081
15408
  const command = new Command("create");
15082
- command.description("Create a new canvas file in the .principal-views folder").requiredOption("-n, --name <name>", 'Name for the canvas file (e.g., "cache-sync-architecture")').option("-f, --force", "Overwrite existing file").action(async (options) => {
15409
+ command.description("Create a new canvas file in the .principal-views folder").requiredOption(
15410
+ "-n, --name <name>",
15411
+ 'Name for the canvas file (e.g., "cache-sync-architecture")'
15412
+ ).option("-f, --force", "Overwrite existing file").action(async (options) => {
15083
15413
  try {
15084
15414
  const vgcDir = (0, import_node_path10.join)(process.cwd(), ".principal-views");
15085
15415
  const canvasFile = (0, import_node_path10.join)(vgcDir, `${options.name}.canvas`);
@@ -15088,7 +15418,9 @@ function createCreateCommand() {
15088
15418
  console.log(source_default.green(`Created directory: .principal-views/`));
15089
15419
  }
15090
15420
  if ((0, import_node_fs9.existsSync)(canvasFile) && !options.force) {
15091
- console.error(source_default.red(`Error: Canvas file already exists: .principal-views/${options.name}.canvas`));
15421
+ console.error(
15422
+ source_default.red(`Error: Canvas file already exists: .principal-views/${options.name}.canvas`)
15423
+ );
15092
15424
  console.log(source_default.yellow(`Use ${source_default.cyan("--force")} to overwrite`));
15093
15425
  process.exit(1);
15094
15426
  }
@@ -15096,7 +15428,9 @@ function createCreateCommand() {
15096
15428
  console.log(source_default.green(`\u2713 Created canvas file: .principal-views/${options.name}.canvas`));
15097
15429
  console.log("");
15098
15430
  console.log(source_default.bold("Next steps:"));
15099
- console.log(` 1. Open ${source_default.cyan(`.principal-views/${options.name}.canvas`)} in your editor`);
15431
+ console.log(
15432
+ ` 1. Open ${source_default.cyan(`.principal-views/${options.name}.canvas`)} in your editor`
15433
+ );
15100
15434
  console.log(` 2. Add nodes and edges to define your architecture`);
15101
15435
  console.log(` 3. Run ${source_default.cyan("privu validate")} to check your configuration`);
15102
15436
  console.log(` 4. Run ${source_default.cyan("privu doctor")} to verify source mappings`);
@@ -15883,6 +16217,18 @@ var validNodeTypes = {
15883
16217
  }
15884
16218
  for (const [typeId, nodeType] of Object.entries(configuration.nodeTypes)) {
15885
16219
  const basePath = `nodeTypes.${typeId}`;
16220
+ if (!nodeType.description) {
16221
+ violations.push({
16222
+ ruleId: "valid-node-types",
16223
+ severity: "error",
16224
+ file: configPath,
16225
+ path: `${basePath}.description`,
16226
+ message: `Node type "${typeId}" is missing required "description" field`,
16227
+ impact: "Node type must have a description explaining its purpose",
16228
+ suggestion: "Add a description field explaining what this node type represents",
16229
+ fixable: false
16230
+ });
16231
+ }
15886
16232
  if (!nodeType.shape) {
15887
16233
  violations.push({
15888
16234
  ruleId: "valid-node-types",
@@ -16285,6 +16631,7 @@ var ALLOWED_FIELDS = {
16285
16631
  root: ["metadata", "nodeTypes", "edgeTypes", "allowedConnections", "validation", "display"],
16286
16632
  metadata: ["name", "version", "description"],
16287
16633
  nodeType: [
16634
+ "description",
16288
16635
  "shape",
16289
16636
  "icon",
16290
16637
  "color",
@@ -17161,11 +17508,7 @@ function createDefaultRulesEngine() {
17161
17508
  }
17162
17509
 
17163
17510
  // src/commands/lint.ts
17164
- var CONFIG_FILE_NAMES2 = [
17165
- ".privurc.yaml",
17166
- ".privurc.yml",
17167
- ".privurc.json"
17168
- ];
17511
+ var CONFIG_FILE_NAMES2 = [".privurc.yaml", ".privurc.yml", ".privurc.json"];
17169
17512
  function findConfig(startDir) {
17170
17513
  let currentDir = (0, import_node_path11.resolve)(startDir);
17171
17514
  while (true) {
@@ -17321,7 +17664,10 @@ function formatJsonOutput(results) {
17321
17664
  }
17322
17665
  function createLintCommand() {
17323
17666
  const command = new Command("lint");
17324
- command.description("Lint graph configuration files").argument("[files...]", "Files or glob patterns to lint (defaults to .principal-views/**/*.yaml)").option("-c, --config <path>", "Path to config file").option("--library <path>", "Path to component library file").option("-q, --quiet", "Only output errors").option("--json", "Output results as JSON").option("--rule <rules...>", "Only run specific rules").option("--ignore-rule <rules...>", "Skip specific rules").action(async (files, options) => {
17667
+ command.description("Lint graph configuration files").argument(
17668
+ "[files...]",
17669
+ "Files or glob patterns to lint (defaults to .principal-views/**/*.yaml)"
17670
+ ).option("-c, --config <path>", "Path to config file").option("--library <path>", "Path to component library file").option("-q, --quiet", "Only output errors").option("--json", "Output results as JSON").option("--rule <rules...>", "Only run specific rules").option("--ignore-rule <rules...>", "Skip specific rules").action(async (files, options) => {
17325
17671
  try {
17326
17672
  const cwd = process.cwd();
17327
17673
  let privuConfig = getDefaultConfig();
@@ -17369,7 +17715,11 @@ function createLintCommand() {
17369
17715
  } else if (privuConfig.include && privuConfig.include.length > 0) {
17370
17716
  patterns = privuConfig.include;
17371
17717
  } else {
17372
- patterns = [".principal-views/**/*.yaml", ".principal-views/**/*.yml", ".principal-views/**/*.json"];
17718
+ patterns = [
17719
+ ".principal-views/**/*.yaml",
17720
+ ".principal-views/**/*.yml",
17721
+ ".principal-views/**/*.json"
17722
+ ];
17373
17723
  }
17374
17724
  const matchedFiles = await globby(patterns, {
17375
17725
  ignore: privuConfig.exclude || ["**/node_modules/**"],
@@ -17384,9 +17734,16 @@ function createLintCommand() {
17384
17734
  });
17385
17735
  if (configFiles.length === 0) {
17386
17736
  if (options.json) {
17387
- console.log(JSON.stringify({ files: [], summary: { totalFiles: 0, totalErrors: 0, totalWarnings: 0, totalFixable: 0 } }));
17737
+ console.log(
17738
+ JSON.stringify({
17739
+ files: [],
17740
+ summary: { totalFiles: 0, totalErrors: 0, totalWarnings: 0, totalFixable: 0 }
17741
+ })
17742
+ );
17388
17743
  } else {
17389
- console.log(source_default.yellow("No configuration files found matching the specified patterns."));
17744
+ console.log(
17745
+ source_default.yellow("No configuration files found matching the specified patterns.")
17746
+ );
17390
17747
  console.log(source_default.dim(`Patterns searched: ${patterns.join(", ")}`));
17391
17748
  }
17392
17749
  return;
@@ -17408,14 +17765,16 @@ function createLintCommand() {
17408
17765
  const loaded = loadGraphConfig(absolutePath);
17409
17766
  if (!loaded) {
17410
17767
  results.set(relativePath, {
17411
- violations: [{
17412
- ruleId: "parse-error",
17413
- severity: "error",
17414
- file: relativePath,
17415
- message: `Could not parse file: ${filePath}`,
17416
- impact: "File cannot be validated",
17417
- fixable: false
17418
- }],
17768
+ violations: [
17769
+ {
17770
+ ruleId: "parse-error",
17771
+ severity: "error",
17772
+ file: relativePath,
17773
+ message: `Could not parse file: ${filePath}`,
17774
+ impact: "File cannot be validated",
17775
+ fixable: false
17776
+ }
17777
+ ],
17419
17778
  errorCount: 1,
17420
17779
  warningCount: 0,
17421
17780
  fixableCount: 0,