@sentriflow/core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +86 -0
  3. package/package.json +60 -0
  4. package/src/constants.ts +77 -0
  5. package/src/engine/RuleExecutor.ts +256 -0
  6. package/src/engine/Runner.ts +312 -0
  7. package/src/engine/SandboxedExecutor.ts +208 -0
  8. package/src/errors.ts +88 -0
  9. package/src/helpers/arista/helpers.ts +1220 -0
  10. package/src/helpers/arista/index.ts +12 -0
  11. package/src/helpers/aruba/helpers.ts +637 -0
  12. package/src/helpers/aruba/index.ts +13 -0
  13. package/src/helpers/cisco/helpers.ts +534 -0
  14. package/src/helpers/cisco/index.ts +11 -0
  15. package/src/helpers/common/helpers.ts +265 -0
  16. package/src/helpers/common/index.ts +5 -0
  17. package/src/helpers/common/validation.ts +280 -0
  18. package/src/helpers/cumulus/helpers.ts +676 -0
  19. package/src/helpers/cumulus/index.ts +12 -0
  20. package/src/helpers/extreme/helpers.ts +422 -0
  21. package/src/helpers/extreme/index.ts +12 -0
  22. package/src/helpers/fortinet/helpers.ts +892 -0
  23. package/src/helpers/fortinet/index.ts +12 -0
  24. package/src/helpers/huawei/helpers.ts +790 -0
  25. package/src/helpers/huawei/index.ts +11 -0
  26. package/src/helpers/index.ts +53 -0
  27. package/src/helpers/juniper/helpers.ts +756 -0
  28. package/src/helpers/juniper/index.ts +12 -0
  29. package/src/helpers/mikrotik/helpers.ts +722 -0
  30. package/src/helpers/mikrotik/index.ts +12 -0
  31. package/src/helpers/nokia/helpers.ts +856 -0
  32. package/src/helpers/nokia/index.ts +11 -0
  33. package/src/helpers/paloalto/helpers.ts +939 -0
  34. package/src/helpers/paloalto/index.ts +12 -0
  35. package/src/helpers/vyos/helpers.ts +429 -0
  36. package/src/helpers/vyos/index.ts +12 -0
  37. package/src/index.ts +30 -0
  38. package/src/json-rules/ExpressionEvaluator.ts +292 -0
  39. package/src/json-rules/HelperRegistry.ts +177 -0
  40. package/src/json-rules/JsonRuleCompiler.ts +339 -0
  41. package/src/json-rules/JsonRuleValidator.ts +371 -0
  42. package/src/json-rules/index.ts +97 -0
  43. package/src/json-rules/schema.json +350 -0
  44. package/src/json-rules/types.ts +303 -0
  45. package/src/pack-loader/PackLoader.ts +332 -0
  46. package/src/pack-loader/index.ts +17 -0
  47. package/src/pack-loader/types.ts +135 -0
  48. package/src/parser/IncrementalParser.ts +527 -0
  49. package/src/parser/Sanitizer.ts +104 -0
  50. package/src/parser/SchemaAwareParser.ts +504 -0
  51. package/src/parser/VendorSchema.ts +72 -0
  52. package/src/parser/vendors/arista-eos.ts +206 -0
  53. package/src/parser/vendors/aruba-aoscx.ts +123 -0
  54. package/src/parser/vendors/aruba-aosswitch.ts +113 -0
  55. package/src/parser/vendors/aruba-wlc.ts +173 -0
  56. package/src/parser/vendors/cisco-ios.ts +110 -0
  57. package/src/parser/vendors/cisco-nxos.ts +107 -0
  58. package/src/parser/vendors/cumulus-linux.ts +161 -0
  59. package/src/parser/vendors/extreme-exos.ts +154 -0
  60. package/src/parser/vendors/extreme-voss.ts +167 -0
  61. package/src/parser/vendors/fortinet-fortigate.ts +217 -0
  62. package/src/parser/vendors/huawei-vrp.ts +192 -0
  63. package/src/parser/vendors/index.ts +1521 -0
  64. package/src/parser/vendors/juniper-junos.ts +230 -0
  65. package/src/parser/vendors/mikrotik-routeros.ts +274 -0
  66. package/src/parser/vendors/nokia-sros.ts +251 -0
  67. package/src/parser/vendors/paloalto-panos.ts +264 -0
  68. package/src/parser/vendors/vyos-vyos.ts +454 -0
  69. package/src/types/ConfigNode.ts +72 -0
  70. package/src/types/DeclarativeRule.ts +158 -0
  71. package/src/types/IRule.ts +270 -0
@@ -0,0 +1,217 @@
1
+ // packages/core/src/parser/vendors/fortinet-fortigate.ts
2
+
3
+ import type { VendorSchema } from '../VendorSchema';
4
+
5
+ /**
6
+ * Fortinet FortiGate (FortiOS) configuration schema.
7
+ *
8
+ * FortiOS uses a distinctive configuration syntax with:
9
+ * 1. "config" to start configuration blocks
10
+ * 2. "edit" to create/modify named entries within a table
11
+ * 3. "next" to end an edit entry
12
+ * 4. "end" to close a config block
13
+ *
14
+ * Key characteristics:
15
+ * - Hierarchical structure using config/edit/next/end
16
+ * - "set" commands for setting values
17
+ * - "unset" commands for removing values
18
+ * - Comments start with #
19
+ * - No braces - uses keywords for hierarchy
20
+ *
21
+ * Configuration structure:
22
+ * ```
23
+ * config system global
24
+ * set hostname "FW-01"
25
+ * set timezone "America/New_York"
26
+ * end
27
+ *
28
+ * config system interface
29
+ * edit "port1"
30
+ * set ip 192.168.1.1 255.255.255.0
31
+ * set allowaccess ping https ssh
32
+ * set type physical
33
+ * next
34
+ * edit "port2"
35
+ * set ip 10.0.0.1 255.255.255.0
36
+ * set allowaccess ping
37
+ * next
38
+ * end
39
+ *
40
+ * config firewall policy
41
+ * edit 1
42
+ * set srcintf "port1"
43
+ * set dstintf "port2"
44
+ * set srcaddr "all"
45
+ * set dstaddr "all"
46
+ * set action accept
47
+ * set schedule "always"
48
+ * set service "ALL"
49
+ * next
50
+ * end
51
+ * ```
52
+ *
53
+ * FortiOS sections include:
54
+ * - config system global - Global system settings
55
+ * - config system interface - Network interfaces
56
+ * - config system admin - Admin users and access
57
+ * - config firewall policy - Security policies
58
+ * - config firewall address - Address objects
59
+ * - config firewall service custom - Service objects
60
+ * - config vpn ipsec phase1-interface - IPsec VPN tunnels
61
+ * - config router static - Static routing
62
+ * - config router bgp - BGP routing
63
+ * - config log syslogd setting - Logging
64
+ * - config user local - Local users
65
+ * - config user group - User groups
66
+ * - config webfilter profile - Web filtering profiles
67
+ * - config antivirus profile - Antivirus profiles
68
+ * - config ips sensor - IPS profiles
69
+ */
70
+ export const FortinetFortiGateSchema: VendorSchema = {
71
+ id: 'fortinet-fortigate',
72
+ name: 'Fortinet FortiGate (FortiOS)',
73
+ useBraceHierarchy: false,
74
+
75
+ commentPatterns: [
76
+ /^#/, // Hash comments
77
+ /^\/\//, // Double-slash comments (some versions)
78
+ ],
79
+ sectionDelimiter: 'end',
80
+
81
+ blockStarters: [
82
+ // ============ DEPTH 0: Top-level config blocks ============
83
+
84
+ // System configuration
85
+ { pattern: /^config\s+system\s+global$/i, depth: 0 },
86
+ { pattern: /^config\s+system\s+interface$/i, depth: 0 },
87
+ { pattern: /^config\s+system\s+admin$/i, depth: 0 },
88
+ { pattern: /^config\s+system\s+dns$/i, depth: 0 },
89
+ { pattern: /^config\s+system\s+ntp$/i, depth: 0 },
90
+ { pattern: /^config\s+system\s+snmp\s+\S+/i, depth: 0 },
91
+ { pattern: /^config\s+system\s+settings$/i, depth: 0 },
92
+ { pattern: /^config\s+system\s+ha$/i, depth: 0 },
93
+ { pattern: /^config\s+system\s+zone$/i, depth: 0 },
94
+ { pattern: /^config\s+system\s+dhcp\s+server$/i, depth: 0 },
95
+ { pattern: /^config\s+system\s+replacemsg\s+\S+/i, depth: 0 },
96
+ { pattern: /^config\s+system\s+accprofile$/i, depth: 0 },
97
+ { pattern: /^config\s+system\s+api-user$/i, depth: 0 },
98
+ { pattern: /^config\s+system\s+automation-\S+/i, depth: 0 },
99
+ { pattern: /^config\s+system\s+virtual-wan-link$/i, depth: 0 },
100
+ { pattern: /^config\s+system\s+sdwan$/i, depth: 0 },
101
+ { pattern: /^config\s+system\s+\S+/i, depth: 0 }, // Catch-all for system config
102
+
103
+ // Firewall configuration
104
+ { pattern: /^config\s+firewall\s+policy$/i, depth: 0 },
105
+ { pattern: /^config\s+firewall\s+policy6$/i, depth: 0 },
106
+ { pattern: /^config\s+firewall\s+address$/i, depth: 0 },
107
+ { pattern: /^config\s+firewall\s+address6$/i, depth: 0 },
108
+ { pattern: /^config\s+firewall\s+addrgrp$/i, depth: 0 },
109
+ { pattern: /^config\s+firewall\s+addrgrp6$/i, depth: 0 },
110
+ { pattern: /^config\s+firewall\s+service\s+custom$/i, depth: 0 },
111
+ { pattern: /^config\s+firewall\s+service\s+group$/i, depth: 0 },
112
+ { pattern: /^config\s+firewall\s+schedule\s+\S+/i, depth: 0 },
113
+ { pattern: /^config\s+firewall\s+vip$/i, depth: 0 },
114
+ { pattern: /^config\s+firewall\s+vip6$/i, depth: 0 },
115
+ { pattern: /^config\s+firewall\s+ippool$/i, depth: 0 },
116
+ { pattern: /^config\s+firewall\s+ippool6$/i, depth: 0 },
117
+ { pattern: /^config\s+firewall\s+central-snat-map$/i, depth: 0 },
118
+ { pattern: /^config\s+firewall\s+shaper\s+\S+/i, depth: 0 },
119
+ { pattern: /^config\s+firewall\s+shaping-policy$/i, depth: 0 },
120
+ { pattern: /^config\s+firewall\s+ssl-ssh-profile$/i, depth: 0 },
121
+ { pattern: /^config\s+firewall\s+profile-group$/i, depth: 0 },
122
+ { pattern: /^config\s+firewall\s+\S+/i, depth: 0 }, // Catch-all for firewall config
123
+
124
+ // VPN configuration
125
+ { pattern: /^config\s+vpn\s+ipsec\s+phase1-interface$/i, depth: 0 },
126
+ { pattern: /^config\s+vpn\s+ipsec\s+phase2-interface$/i, depth: 0 },
127
+ { pattern: /^config\s+vpn\s+ssl\s+settings$/i, depth: 0 },
128
+ { pattern: /^config\s+vpn\s+ssl\s+web\s+\S+/i, depth: 0 },
129
+ { pattern: /^config\s+vpn\s+\S+/i, depth: 0 }, // Catch-all for VPN config
130
+
131
+ // Router configuration
132
+ { pattern: /^config\s+router\s+static$/i, depth: 0 },
133
+ { pattern: /^config\s+router\s+static6$/i, depth: 0 },
134
+ { pattern: /^config\s+router\s+policy$/i, depth: 0 },
135
+ { pattern: /^config\s+router\s+bgp$/i, depth: 0 },
136
+ { pattern: /^config\s+router\s+ospf$/i, depth: 0 },
137
+ { pattern: /^config\s+router\s+ospf6$/i, depth: 0 },
138
+ { pattern: /^config\s+router\s+rip$/i, depth: 0 },
139
+ { pattern: /^config\s+router\s+access-list$/i, depth: 0 },
140
+ { pattern: /^config\s+router\s+prefix-list$/i, depth: 0 },
141
+ { pattern: /^config\s+router\s+route-map$/i, depth: 0 },
142
+ { pattern: /^config\s+router\s+\S+/i, depth: 0 }, // Catch-all for router config
143
+
144
+ // Logging configuration
145
+ { pattern: /^config\s+log\s+syslogd\s+setting$/i, depth: 0 },
146
+ { pattern: /^config\s+log\s+syslogd\d?\s+\S+/i, depth: 0 },
147
+ { pattern: /^config\s+log\s+fortianalyzer\s+\S+/i, depth: 0 },
148
+ { pattern: /^config\s+log\s+disk\s+\S+/i, depth: 0 },
149
+ { pattern: /^config\s+log\s+memory\s+\S+/i, depth: 0 },
150
+ { pattern: /^config\s+log\s+\S+/i, depth: 0 }, // Catch-all for log config
151
+
152
+ // User and authentication configuration
153
+ { pattern: /^config\s+user\s+local$/i, depth: 0 },
154
+ { pattern: /^config\s+user\s+group$/i, depth: 0 },
155
+ { pattern: /^config\s+user\s+ldap$/i, depth: 0 },
156
+ { pattern: /^config\s+user\s+radius$/i, depth: 0 },
157
+ { pattern: /^config\s+user\s+tacacs\+$/i, depth: 0 },
158
+ { pattern: /^config\s+user\s+fsso$/i, depth: 0 },
159
+ { pattern: /^config\s+user\s+\S+/i, depth: 0 }, // Catch-all for user config
160
+
161
+ // Security profiles
162
+ { pattern: /^config\s+antivirus\s+profile$/i, depth: 0 },
163
+ { pattern: /^config\s+webfilter\s+profile$/i, depth: 0 },
164
+ { pattern: /^config\s+webfilter\s+urlfilter$/i, depth: 0 },
165
+ { pattern: /^config\s+webfilter\s+content$/i, depth: 0 },
166
+ { pattern: /^config\s+webfilter\s+ftgd-local-cat$/i, depth: 0 },
167
+ { pattern: /^config\s+ips\s+sensor$/i, depth: 0 },
168
+ { pattern: /^config\s+ips\s+\S+/i, depth: 0 },
169
+ { pattern: /^config\s+application\s+list$/i, depth: 0 },
170
+ { pattern: /^config\s+application\s+\S+/i, depth: 0 },
171
+ { pattern: /^config\s+dlp\s+\S+/i, depth: 0 },
172
+ { pattern: /^config\s+spamfilter\s+\S+/i, depth: 0 },
173
+ { pattern: /^config\s+emailfilter\s+\S+/i, depth: 0 },
174
+ { pattern: /^config\s+icap\s+\S+/i, depth: 0 },
175
+ { pattern: /^config\s+voip\s+profile$/i, depth: 0 },
176
+ { pattern: /^config\s+waf\s+profile$/i, depth: 0 },
177
+ { pattern: /^config\s+dnsfilter\s+profile$/i, depth: 0 },
178
+ { pattern: /^config\s+videofilter\s+profile$/i, depth: 0 },
179
+ { pattern: /^config\s+file-filter\s+profile$/i, depth: 0 },
180
+ { pattern: /^config\s+ssh-filter\s+profile$/i, depth: 0 },
181
+ { pattern: /^config\s+cifs\s+profile$/i, depth: 0 },
182
+
183
+ // Certificate configuration
184
+ { pattern: /^config\s+certificate\s+\S+/i, depth: 0 },
185
+ { pattern: /^config\s+vpn\s+certificate\s+\S+/i, depth: 0 },
186
+
187
+ // Wireless configuration
188
+ { pattern: /^config\s+wireless-controller\s+\S+/i, depth: 0 },
189
+
190
+ // Switch controller (FortiSwitch integration)
191
+ { pattern: /^config\s+switch-controller\s+\S+/i, depth: 0 },
192
+
193
+ // Endpoint control
194
+ { pattern: /^config\s+endpoint-control\s+\S+/i, depth: 0 },
195
+
196
+ // Global/generic config blocks
197
+ { pattern: /^config\s+\S+/i, depth: 0 }, // Generic config block starter
198
+
199
+ // ============ DEPTH 1: Edit entries within config blocks ============
200
+
201
+ // Edit with quoted name (most common in FortiOS)
202
+ { pattern: /^edit\s+"[^"]+"/i, depth: 1 },
203
+ { pattern: /^edit\s+'[^']+'/i, depth: 1 },
204
+ // Edit with unquoted name or number (e.g., policy IDs)
205
+ { pattern: /^edit\s+\S+/i, depth: 1 },
206
+
207
+ // ============ DEPTH 2: Nested config within edit blocks ============
208
+
209
+ // Nested config blocks inside edit entries (e.g., BGP neighbor config)
210
+ { pattern: /^config\s+\S+/i, depth: 2 },
211
+ ],
212
+
213
+ blockEnders: [
214
+ /^end$/i, // Closes config block
215
+ /^next$/i, // Closes edit entry
216
+ ],
217
+ };
@@ -0,0 +1,192 @@
1
+ // packages/core/src/parser/vendors/huawei-vrp.ts
2
+
3
+ import type { VendorSchema } from '../VendorSchema';
4
+
5
+ /**
6
+ * Huawei VRP (Versatile Routing Platform) configuration schema.
7
+ *
8
+ * Huawei VRP uses indentation-based hierarchy similar to Cisco IOS,
9
+ * with '#' as the section delimiter and 'quit' or 'return' to exit blocks.
10
+ *
11
+ * VRP View Hierarchy:
12
+ * - User View: <Huawei> - Initial access, limited commands
13
+ * - System View: [Huawei] - Global configuration (enter via 'system-view')
14
+ * - Interface View: [Huawei-GigabitEthernet0/0/1] - Interface config
15
+ * - Protocol View: [Huawei-ospf-1] - Routing protocol config
16
+ * - AAA View: [Huawei-aaa] - AAA configuration
17
+ *
18
+ * Configuration structure:
19
+ * - Top-level: interface, ospf, bgp, vlan, aaa, acl, user-interface, etc.
20
+ * - Nested: area inside ospf, peer inside bgp, address-family inside bgp
21
+ * - Deeply nested: rules inside ACL, local-user inside aaa
22
+ *
23
+ * Distinctive patterns:
24
+ * - sysname for hostname (vs Cisco's hostname)
25
+ * - Interface naming: GigabitEthernet X/Y/Z, XGigabitEthernet, 40GE, 100GE
26
+ * - undo command for negation (vs Cisco's 'no')
27
+ * - quit to exit views (vs Cisco's exit)
28
+ * - '#' as section delimiter in config files
29
+ * - display commands for show (vs Cisco's show)
30
+ */
31
+ export const HuaweiVRPSchema: VendorSchema = {
32
+ id: 'huawei-vrp',
33
+ name: 'Huawei VRP',
34
+ useBraceHierarchy: false,
35
+
36
+ // Comments in VRP config files start with # or !
37
+ // The # is also used as a section delimiter
38
+ commentPatterns: [/^#$/, /^!/],
39
+ sectionDelimiter: '#',
40
+
41
+ blockStarters: [
42
+ // ============ DEPTH 0: Top-level blocks ============
43
+
44
+ // Interface blocks - Huawei naming conventions
45
+ { pattern: /^interface\s+\S+/i, depth: 0 },
46
+
47
+ // VLAN interface (Vlanif in Huawei)
48
+ { pattern: /^interface\s+Vlanif\s*\d+/i, depth: 0 },
49
+
50
+ // Routing protocol blocks
51
+ { pattern: /^ospf\s+\d+/i, depth: 0 },
52
+ { pattern: /^ospfv3\s+\d+/i, depth: 0 },
53
+ { pattern: /^bgp\s+\d+/i, depth: 0 },
54
+ { pattern: /^isis\s+\d+/i, depth: 0 },
55
+ { pattern: /^rip\s+\d+/i, depth: 0 },
56
+ { pattern: /^mpls$/i, depth: 0 },
57
+ { pattern: /^mpls\s+ldp$/i, depth: 0 },
58
+ { pattern: /^mpls\s+l2vpn$/i, depth: 0 },
59
+ { pattern: /^mpls\s+te$/i, depth: 0 },
60
+
61
+ // VLAN configuration
62
+ { pattern: /^vlan\s+\d+/i, depth: 0 },
63
+ { pattern: /^vlan\s+batch\s+/i, depth: 0 },
64
+
65
+ // AAA and security
66
+ { pattern: /^aaa$/i, depth: 0 },
67
+ { pattern: /^acl\s+\d+/i, depth: 0 },
68
+ { pattern: /^acl\s+name\s+\S+/i, depth: 0 },
69
+ { pattern: /^acl\s+(number\s+)?\d+/i, depth: 0 },
70
+ { pattern: /^traffic\s+classifier\s+\S+/i, depth: 0 },
71
+ { pattern: /^traffic\s+behavior\s+\S+/i, depth: 0 },
72
+ { pattern: /^traffic\s+policy\s+\S+/i, depth: 0 },
73
+
74
+ // User and line configuration
75
+ { pattern: /^user-interface\s+\S+/i, depth: 0 },
76
+ { pattern: /^local-user\s+\S+/i, depth: 0 },
77
+
78
+ // RADIUS and TACACS
79
+ { pattern: /^radius-server\s+group\s+\S+/i, depth: 0 },
80
+ { pattern: /^radius-server\s+template\s+\S+/i, depth: 0 },
81
+ { pattern: /^hwtacacs-server\s+template\s+\S+/i, depth: 0 },
82
+
83
+ // VPN and tunneling
84
+ { pattern: /^ip\s+vpn-instance\s+\S+/i, depth: 0 },
85
+ { pattern: /^ipsec\s+proposal\s+\S+/i, depth: 0 },
86
+ { pattern: /^ipsec\s+policy\s+\S+/i, depth: 0 },
87
+ { pattern: /^ike\s+proposal\s+\S+/i, depth: 0 },
88
+ { pattern: /^ike\s+peer\s+\S+/i, depth: 0 },
89
+
90
+ // SNMP configuration
91
+ { pattern: /^snmp-agent$/i, depth: 0 },
92
+
93
+ // NTP configuration
94
+ { pattern: /^ntp-service$/i, depth: 0 },
95
+
96
+ // SSH and SFTP
97
+ { pattern: /^ssh\s+server$/i, depth: 0 },
98
+ { pattern: /^sftp\s+server$/i, depth: 0 },
99
+
100
+ // DHCP configuration
101
+ { pattern: /^dhcp\s+enable$/i, depth: 0 },
102
+ { pattern: /^ip\s+pool\s+\S+/i, depth: 0 },
103
+
104
+ // QoS
105
+ { pattern: /^qos$/i, depth: 0 },
106
+ { pattern: /^qos\s+queue-profile\s+\S+/i, depth: 0 },
107
+ { pattern: /^diffserv\s+domain\s+\S+/i, depth: 0 },
108
+
109
+ // Multicast
110
+ { pattern: /^multicast\s+routing-enable$/i, depth: 0 },
111
+ { pattern: /^igmp-snooping$/i, depth: 0 },
112
+
113
+ // Spanning Tree
114
+ { pattern: /^stp$/i, depth: 0 },
115
+ { pattern: /^stp\s+region-configuration$/i, depth: 0 },
116
+
117
+ // Link aggregation
118
+ { pattern: /^interface\s+Eth-Trunk\s*\d+/i, depth: 0 },
119
+
120
+ // Port groups
121
+ { pattern: /^port-group\s+\S+/i, depth: 0 },
122
+
123
+ // Static routes (treated as blocks in some contexts)
124
+ { pattern: /^ip\s+route-static\s+/i, depth: 0 },
125
+
126
+ // Route policy
127
+ { pattern: /^route-policy\s+\S+/i, depth: 0 },
128
+ { pattern: /^ip\s+prefix-list\s+\S+/i, depth: 0 },
129
+ { pattern: /^ip\s+ip-prefix\s+\S+/i, depth: 0 },
130
+ { pattern: /^ip\s+community-filter\s+/i, depth: 0 },
131
+ { pattern: /^ip\s+as-path-filter\s+/i, depth: 0 },
132
+
133
+ // NOTE: vrrp vrid is NOT a block starter - it's an interface-level command
134
+ // Commands like "vrrp vrid 1 virtual-ip x.x.x.x" are children of interface blocks
135
+ // Do NOT add vrrp vrid as a block starter here
136
+
137
+ // BFD
138
+ { pattern: /^bfd$/i, depth: 0 },
139
+
140
+ // Netstream/Flow
141
+ { pattern: /^netstream$/i, depth: 0 },
142
+ { pattern: /^ip\s+netstream$/i, depth: 0 },
143
+
144
+ // Stack configuration
145
+ { pattern: /^stack$/i, depth: 0 },
146
+
147
+ // LLDP
148
+ { pattern: /^lldp$/i, depth: 0 },
149
+
150
+ // ============ DEPTH 1: Inside protocol blocks ============
151
+
152
+ // OSPF areas
153
+ { pattern: /^area\s+[\d.]+/i, depth: 1 },
154
+
155
+ // BGP address families
156
+ { pattern: /^ipv4-family\s+\S+/i, depth: 1 },
157
+ { pattern: /^ipv6-family\s+\S+/i, depth: 1 },
158
+ { pattern: /^l2vpn-family\s+/i, depth: 1 },
159
+ { pattern: /^vpls-family\s+/i, depth: 1 },
160
+
161
+ // BGP peer groups
162
+ { pattern: /^group\s+\S+/i, depth: 1 },
163
+
164
+ // AAA schemes
165
+ { pattern: /^authentication-scheme\s+\S+/i, depth: 1 },
166
+ { pattern: /^authorization-scheme\s+\S+/i, depth: 1 },
167
+ { pattern: /^accounting-scheme\s+\S+/i, depth: 1 },
168
+ { pattern: /^domain\s+\S+/i, depth: 1 },
169
+ { pattern: /^recording-scheme\s+\S+/i, depth: 1 },
170
+
171
+ // ACL rules (numbered ACL depth)
172
+ { pattern: /^rule\s+\d+/i, depth: 1 },
173
+
174
+ // Route policy nodes
175
+ { pattern: /^node\s+\d+/i, depth: 1 },
176
+
177
+ // ============ DEPTH 2: Deeply nested blocks ============
178
+
179
+ // VRF inside address-family
180
+ { pattern: /^vpn-instance\s+\S+/i, depth: 2 },
181
+
182
+ // Network inside OSPF area
183
+ { pattern: /^network\s+[\d.]+/i, depth: 2 },
184
+ ],
185
+
186
+ blockEnders: [
187
+ /^quit$/i,
188
+ /^return$/i,
189
+ // Exit from specific views
190
+ /^q$/i,
191
+ ],
192
+ };