@tikoci/centrs 0.1.3 → 0.1.6

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 (107) hide show
  1. package/CHANGELOG.md +348 -0
  2. package/GLOSSARY.txt +252 -0
  3. package/LICENSE +21 -0
  4. package/README.md +44 -12
  5. package/commands/AGENTS.md +14 -5
  6. package/commands/api/AGENTS.md +13 -1
  7. package/commands/api/README.md +56 -26
  8. package/commands/api/examples.md +46 -1
  9. package/commands/btest/README.md +21 -32
  10. package/commands/check/README.md +6 -1
  11. package/commands/discover/README.md +5 -11
  12. package/commands/execute/README.md +77 -36
  13. package/commands/execute/examples.md +120 -10
  14. package/commands/explain/README.md +2756 -0
  15. package/commands/explain/examples.md +702 -0
  16. package/commands/mcp/README.md +7 -4
  17. package/commands/mcp/examples.md +2 -2
  18. package/commands/retrieve/README.md +25 -27
  19. package/commands/retrieve/examples.md +16 -0
  20. package/commands/terminal/examples.md +7 -1
  21. package/commands/transfer/README.md +28 -20
  22. package/commands/transfer/examples.md +29 -0
  23. package/docs/CLI.md +353 -0
  24. package/docs/CONSTITUTION.md +138 -30
  25. package/docs/MATRIX.md +92 -18
  26. package/docs/errors/README.md +3 -0
  27. package/docs/errors/quickchr/machine-not-found.md +22 -0
  28. package/docs/errors/quickchr/machine-stopped.md +20 -0
  29. package/docs/errors/quickchr/package-unavailable.md +27 -0
  30. package/docs/errors/quickchr/unsupported-via.md +35 -0
  31. package/docs/errors/quickchr/unsupported.md +35 -0
  32. package/docs/errors/routeros/version-unsupported.md +26 -0
  33. package/docs/errors/transport/provider-trust.md +29 -0
  34. package/docs/errors/usage/stdin-ignored.md +28 -0
  35. package/docs/errors/validation/syntax.md +29 -4
  36. package/docs/errors/validation/unknown-attribute.md +37 -4
  37. package/package.json +56 -10
  38. package/src/api-fanout.ts +46 -18
  39. package/src/api.ts +351 -121
  40. package/src/cli/api.ts +26 -7
  41. package/src/cli/btest.ts +19 -3
  42. package/src/cli/execute.ts +25 -6
  43. package/src/cli/explain.ts +503 -0
  44. package/src/cli/retrieve.ts +33 -1
  45. package/src/cli/selection.ts +71 -11
  46. package/src/cli/settings.ts +2 -2
  47. package/src/cli/terminal.ts +1 -1
  48. package/src/cli/transfer.ts +23 -6
  49. package/src/cli.ts +15 -2
  50. package/src/core/envelope.ts +58 -2
  51. package/src/core/error-catalog.ts +42 -1
  52. package/src/core/execute-command.ts +148 -0
  53. package/src/core/inspect.ts +36 -4
  54. package/src/core/preflight.ts +306 -0
  55. package/src/core/routeros-string.ts +24 -0
  56. package/src/core/version.ts +4 -0
  57. package/src/core/yaml.ts +86 -0
  58. package/src/errors.ts +1 -0
  59. package/src/execute-fanout.ts +47 -18
  60. package/src/execute.ts +339 -307
  61. package/src/explain/arg-tokens.ts +151 -0
  62. package/src/explain/args.ts +1749 -0
  63. package/src/explain/blocks.ts +175 -0
  64. package/src/explain/brace-slots.ts +143 -0
  65. package/src/explain/brace-tokens.ts +39 -0
  66. package/src/explain/catalog.ts +1343 -0
  67. package/src/explain/coordinates.ts +488 -0
  68. package/src/explain/defects.ts +218 -0
  69. package/src/explain/escape-tokens.ts +77 -0
  70. package/src/explain/highlight-projection.ts +308 -0
  71. package/src/explain/is-known-menu.ts +17 -0
  72. package/src/explain/menus.ts +668 -0
  73. package/src/explain/operator-tokens.ts +316 -0
  74. package/src/explain/operators.ts +465 -0
  75. package/src/explain/path-tokens.ts +150 -0
  76. package/src/explain/pathresolve.ts +1569 -0
  77. package/src/explain/quoted-string.ts +331 -0
  78. package/src/explain/scope-brace.ts +461 -0
  79. package/src/explain/segment.ts +1165 -0
  80. package/src/explain/separator.ts +187 -0
  81. package/src/explain/split-owner.ts +194 -0
  82. package/src/explain/string-tokens.ts +77 -0
  83. package/src/explain/symbol-values.ts +556 -0
  84. package/src/explain/symbols.ts +1617 -0
  85. package/src/explain/token-ranges.ts +72 -0
  86. package/src/explain/transport.ts +514 -0
  87. package/src/explain/value-tokens.ts +83 -0
  88. package/src/explain/values.ts +357 -0
  89. package/src/explain/verbs.ts +64 -0
  90. package/src/explain/verbsplit.ts +955 -0
  91. package/src/explain/write.ts +856 -0
  92. package/src/explain.ts +2602 -0
  93. package/src/index.ts +225 -6
  94. package/src/mcp/server.ts +2 -1
  95. package/src/offline-gate.ts +148 -0
  96. package/src/protocols/mac-telnet-console.ts +61 -17
  97. package/src/resolver/facts.ts +1 -1
  98. package/src/resolver/index.ts +23 -4
  99. package/src/resolver/quickchr-provider.ts +597 -0
  100. package/src/resolver/selection.ts +99 -12
  101. package/src/resolver/service-endpoint.ts +155 -0
  102. package/src/resolver/target.ts +1 -1
  103. package/src/retrieve-fanout.ts +27 -13
  104. package/src/retrieve.ts +82 -77
  105. package/src/settings.ts +2 -1
  106. package/src/transfer-fanout.ts +43 -26
  107. package/src/transfer.ts +88 -45
@@ -0,0 +1,668 @@
1
+ /**
2
+ * RouterOS menu (container) paths — GENERATED, do not hand-edit.
3
+ *
4
+ * Regenerate with `bun run explain:menus`; `bun run explain:menus --check` is
5
+ * the drift gate. The generator (`scripts/gen-explain-menus.ts`) carries the
6
+ * full rationale, the source pin, and why absence here is safe.
7
+ *
8
+ * Union of the `dir` and `path` nodes in 6 pinned restraml typed trees
9
+ * (`https://tikoci.github.io/restraml/`), all extra-packages builds:
10
+ *
11
+ * | Tree | Arch | RouterOS | Nodes | Containers |
12
+ * | ---- | ---- | -------- | ----- | ---------- |
13
+ * | `7.10.2/extra/inspect.json` | x86 | 7.10.2 | 29,086 | 458 |
14
+ * | `7.16/extra/inspect.json` | x86 | 7.16 | 34,876 | 522 |
15
+ * | `7.24.2/extra/deep-inspect.x86.json` | x86 | 7.24.2 | 41,345 | 554 |
16
+ * | `7.24.2/extra/deep-inspect.arm64.json` | arm64 | 7.24.2 | 42,691 | 575 |
17
+ * | `7.25beta3/extra/deep-inspect.x86.json` | x86 | 7.25beta3 | 41,798 | 557 |
18
+ * | `7.25beta3/extra/deep-inspect.arm64.json` | arm64 | 7.25beta3 | 43,148 | 578 |
19
+ *
20
+ * Zero node-type conflicts across those trees — no `dir`↔`cmd` flip across
21
+ * 4 versions or across architectures — which is what makes the union
22
+ * version-less rather than version-keyed. Generation aborts if that ever stops
23
+ * holding.
24
+ *
25
+ * **This table is a floor.** A path missing here is not confirmed as
26
+ * navigation, so `write.ts` abstains on it — the pre-#207 behaviour for an
27
+ * unrecognized menu, never a wrong answer. A COMMAND wrongly listed here would
28
+ * be a wrong answer, which is what the pin and the conflict check protect.
29
+ */
30
+
31
+ /** Every container path the pinned trees agree on, lower-cased and sorted. */
32
+ export const MENU_PATHS: ReadonlySet<string> = new Set([
33
+ "/app",
34
+ "/app/network",
35
+ "/app/settings",
36
+ "/caps-man",
37
+ "/caps-man/aaa",
38
+ "/caps-man/access-list",
39
+ "/caps-man/actual-interface-configuration",
40
+ "/caps-man/channel",
41
+ "/caps-man/configuration",
42
+ "/caps-man/datapath",
43
+ "/caps-man/interface",
44
+ "/caps-man/manager",
45
+ "/caps-man/manager/interface",
46
+ "/caps-man/provisioning",
47
+ "/caps-man/radio",
48
+ "/caps-man/rates",
49
+ "/caps-man/registration-table",
50
+ "/caps-man/remote-cap",
51
+ "/caps-man/security",
52
+ "/certificate",
53
+ "/certificate/builtin",
54
+ "/certificate/crl",
55
+ "/certificate/scep-server",
56
+ "/certificate/scep-server/otp",
57
+ "/certificate/scep-server/ra",
58
+ "/certificate/scep-server/requests",
59
+ "/certificate/settings",
60
+ "/console",
61
+ "/console/settings",
62
+ "/container",
63
+ "/container/config",
64
+ "/container/envs",
65
+ "/container/layers",
66
+ "/container/log",
67
+ "/container/mounts",
68
+ "/disk",
69
+ "/disk/btrfs",
70
+ "/disk/btrfs/filesystem",
71
+ "/disk/btrfs/subvolume",
72
+ "/disk/btrfs/transfer",
73
+ "/disk/settings",
74
+ "/disk/smb-share",
75
+ "/disk/smb-user",
76
+ "/dude",
77
+ "/dude/agent",
78
+ "/dude/device",
79
+ "/dude/device-type",
80
+ "/dude/notification",
81
+ "/dude/probe",
82
+ "/dude/ros",
83
+ "/dude/ros/address",
84
+ "/dude/ros/arp",
85
+ "/dude/ros/health",
86
+ "/dude/ros/interface",
87
+ "/dude/ros/lease",
88
+ "/dude/ros/neighbor",
89
+ "/dude/ros/queue",
90
+ "/dude/ros/registration-table",
91
+ "/dude/ros/resource",
92
+ "/dude/ros/route",
93
+ "/dude/ros/routerboard",
94
+ "/dude/service",
95
+ "/dude/settings",
96
+ "/environment",
97
+ "/file",
98
+ "/file/rsync-daemon",
99
+ "/file/sync",
100
+ "/interface",
101
+ "/interface/6to4",
102
+ "/interface/bonding",
103
+ "/interface/bridge",
104
+ "/interface/bridge/calea",
105
+ "/interface/bridge/filter",
106
+ "/interface/bridge/host",
107
+ "/interface/bridge/mdb",
108
+ "/interface/bridge/msti",
109
+ "/interface/bridge/nat",
110
+ "/interface/bridge/port",
111
+ "/interface/bridge/port-controller",
112
+ "/interface/bridge/port-controller/device",
113
+ "/interface/bridge/port-controller/port",
114
+ "/interface/bridge/port-controller/port/poe",
115
+ "/interface/bridge/port-extender",
116
+ "/interface/bridge/port/mst-override",
117
+ "/interface/bridge/settings",
118
+ "/interface/bridge/vlan",
119
+ "/interface/bridge/vlan/mvrp",
120
+ "/interface/detect-internet",
121
+ "/interface/detect-internet/state",
122
+ "/interface/dot1x",
123
+ "/interface/dot1x/client",
124
+ "/interface/dot1x/server",
125
+ "/interface/dot1x/server/active",
126
+ "/interface/dot1x/server/state",
127
+ "/interface/eoip",
128
+ "/interface/eoipv6",
129
+ "/interface/ethernet",
130
+ "/interface/ethernet/pon",
131
+ "/interface/ethernet/switch",
132
+ "/interface/ethernet/switch/host",
133
+ "/interface/ethernet/switch/port",
134
+ "/interface/ethernet/switch/port-isolation",
135
+ "/interface/ethernet/switch/rule",
136
+ "/interface/ethernet/switch/vlan",
137
+ "/interface/gre",
138
+ "/interface/gre6",
139
+ "/interface/ipip",
140
+ "/interface/ipipv6",
141
+ "/interface/l2tp-client",
142
+ "/interface/l2tp-ether",
143
+ "/interface/l2tp-server",
144
+ "/interface/l2tp-server/server",
145
+ "/interface/list",
146
+ "/interface/list/member",
147
+ "/interface/lte",
148
+ "/interface/lte/apn",
149
+ "/interface/lte/esim",
150
+ "/interface/lte/settings",
151
+ "/interface/macsec",
152
+ "/interface/macsec/profile",
153
+ "/interface/macvlan",
154
+ "/interface/mesh",
155
+ "/interface/mesh/fdb",
156
+ "/interface/mesh/port",
157
+ "/interface/ovpn-client",
158
+ "/interface/ovpn-server",
159
+ "/interface/ovpn-server/server",
160
+ "/interface/ppp-client",
161
+ "/interface/ppp-server",
162
+ "/interface/pppoe-client",
163
+ "/interface/pppoe-server",
164
+ "/interface/pppoe-server/server",
165
+ "/interface/pptp-client",
166
+ "/interface/pptp-server",
167
+ "/interface/pptp-server/server",
168
+ "/interface/sstp-client",
169
+ "/interface/sstp-server",
170
+ "/interface/sstp-server/server",
171
+ "/interface/veth",
172
+ "/interface/vlan",
173
+ "/interface/vpls",
174
+ "/interface/vrrp",
175
+ "/interface/vxlan",
176
+ "/interface/vxlan/fdb",
177
+ "/interface/vxlan/vteps",
178
+ "/interface/wifi",
179
+ "/interface/wifi/aaa",
180
+ "/interface/wifi/access-list",
181
+ "/interface/wifi/cap",
182
+ "/interface/wifi/capsman",
183
+ "/interface/wifi/capsman/remote-cap",
184
+ "/interface/wifi/channel",
185
+ "/interface/wifi/configuration",
186
+ "/interface/wifi/datapath",
187
+ "/interface/wifi/interworking",
188
+ "/interface/wifi/network",
189
+ "/interface/wifi/network/radio",
190
+ "/interface/wifi/provisioning",
191
+ "/interface/wifi/radio",
192
+ "/interface/wifi/radio/settings",
193
+ "/interface/wifi/registration-table",
194
+ "/interface/wifi/security",
195
+ "/interface/wifi/security/multi-passphrase",
196
+ "/interface/wifi/steering",
197
+ "/interface/wifi/steering/neighbor-group",
198
+ "/interface/wifiwave2",
199
+ "/interface/wifiwave2/aaa",
200
+ "/interface/wifiwave2/access-list",
201
+ "/interface/wifiwave2/actual-configuration",
202
+ "/interface/wifiwave2/cap",
203
+ "/interface/wifiwave2/capsman",
204
+ "/interface/wifiwave2/capsman/remote-cap",
205
+ "/interface/wifiwave2/channel",
206
+ "/interface/wifiwave2/configuration",
207
+ "/interface/wifiwave2/datapath",
208
+ "/interface/wifiwave2/interworking",
209
+ "/interface/wifiwave2/provisioning",
210
+ "/interface/wifiwave2/radio",
211
+ "/interface/wifiwave2/registration-table",
212
+ "/interface/wifiwave2/security",
213
+ "/interface/wireguard",
214
+ "/interface/wireguard/peers",
215
+ "/interface/wireless",
216
+ "/interface/wireless/access-list",
217
+ "/interface/wireless/align",
218
+ "/interface/wireless/cap",
219
+ "/interface/wireless/channels",
220
+ "/interface/wireless/connect-list",
221
+ "/interface/wireless/info",
222
+ "/interface/wireless/interworking-profiles",
223
+ "/interface/wireless/manual-tx-power-table",
224
+ "/interface/wireless/nstreme",
225
+ "/interface/wireless/nstreme-dual",
226
+ "/interface/wireless/registration-table",
227
+ "/interface/wireless/security-profiles",
228
+ "/interface/wireless/sniffer",
229
+ "/interface/wireless/sniffer/packet",
230
+ "/interface/wireless/snooper",
231
+ "/interface/wireless/wds",
232
+ "/interface/xfrm",
233
+ "/iot",
234
+ "/iot/bluetooth",
235
+ "/iot/bluetooth/advertisers",
236
+ "/iot/bluetooth/advertisers/ad-structures",
237
+ "/iot/bluetooth/connections",
238
+ "/iot/bluetooth/connections/async-data",
239
+ "/iot/bluetooth/connections/characteristics",
240
+ "/iot/bluetooth/peripheral-devices",
241
+ "/iot/bluetooth/scanners",
242
+ "/iot/bluetooth/scanners/advertisements",
243
+ "/iot/bluetooth/whitelist",
244
+ "/iot/lora",
245
+ "/iot/lora/channels",
246
+ "/iot/lora/joineui",
247
+ "/iot/lora/netid",
248
+ "/iot/lora/radios",
249
+ "/iot/lora/servers",
250
+ "/iot/lora/traffic",
251
+ "/iot/lora/traffic/options",
252
+ "/iot/modbus",
253
+ "/iot/modbus/security-rules",
254
+ "/iot/mqtt",
255
+ "/iot/mqtt/brokers",
256
+ "/iot/mqtt/subscriptions",
257
+ "/iot/mqtt/subscriptions/recv",
258
+ "/iot/wiliot",
259
+ "/iot/wiliot/bluetooth-traffic",
260
+ "/iot/wiliot/mqtt-traffic",
261
+ "/iot/wiliot/options",
262
+ "/iot/wiliot/servers",
263
+ "/ip",
264
+ "/ip/address",
265
+ "/ip/arp",
266
+ "/ip/cloud",
267
+ "/ip/cloud/advanced",
268
+ "/ip/cloud/back-to-home-file",
269
+ "/ip/cloud/back-to-home-file/settings",
270
+ "/ip/cloud/back-to-home-user",
271
+ "/ip/dhcp-client",
272
+ "/ip/dhcp-client/option",
273
+ "/ip/dhcp-relay",
274
+ "/ip/dhcp-server",
275
+ "/ip/dhcp-server/alert",
276
+ "/ip/dhcp-server/config",
277
+ "/ip/dhcp-server/lease",
278
+ "/ip/dhcp-server/matcher",
279
+ "/ip/dhcp-server/network",
280
+ "/ip/dhcp-server/option",
281
+ "/ip/dhcp-server/option/sets",
282
+ "/ip/dns",
283
+ "/ip/dns/adlist",
284
+ "/ip/dns/cache",
285
+ "/ip/dns/cache/all",
286
+ "/ip/dns/forwarders",
287
+ "/ip/dns/static",
288
+ "/ip/firewall",
289
+ "/ip/firewall/address-list",
290
+ "/ip/firewall/calea",
291
+ "/ip/firewall/connection",
292
+ "/ip/firewall/connection/tracking",
293
+ "/ip/firewall/filter",
294
+ "/ip/firewall/layer7-protocol",
295
+ "/ip/firewall/mangle",
296
+ "/ip/firewall/nat",
297
+ "/ip/firewall/raw",
298
+ "/ip/firewall/service-port",
299
+ "/ip/hotspot",
300
+ "/ip/hotspot/active",
301
+ "/ip/hotspot/cookie",
302
+ "/ip/hotspot/host",
303
+ "/ip/hotspot/ip-binding",
304
+ "/ip/hotspot/profile",
305
+ "/ip/hotspot/service-port",
306
+ "/ip/hotspot/user",
307
+ "/ip/hotspot/user/profile",
308
+ "/ip/hotspot/walled-garden",
309
+ "/ip/hotspot/walled-garden/ip",
310
+ "/ip/ipsec",
311
+ "/ip/ipsec/active-peers",
312
+ "/ip/ipsec/identity",
313
+ "/ip/ipsec/installed-sa",
314
+ "/ip/ipsec/key",
315
+ "/ip/ipsec/key/psk",
316
+ "/ip/ipsec/key/rsa",
317
+ "/ip/ipsec/mode-config",
318
+ "/ip/ipsec/peer",
319
+ "/ip/ipsec/policy",
320
+ "/ip/ipsec/policy/group",
321
+ "/ip/ipsec/profile",
322
+ "/ip/ipsec/proposal",
323
+ "/ip/ipsec/settings",
324
+ "/ip/ipsec/statistics",
325
+ "/ip/kid-control",
326
+ "/ip/kid-control/device",
327
+ "/ip/media",
328
+ "/ip/media/settings",
329
+ "/ip/nat-pmp",
330
+ "/ip/nat-pmp/interfaces",
331
+ "/ip/neighbor",
332
+ "/ip/neighbor/discovery-settings",
333
+ "/ip/neighbor/lldp",
334
+ "/ip/packing",
335
+ "/ip/pool",
336
+ "/ip/pool/used",
337
+ "/ip/proxy",
338
+ "/ip/proxy/access",
339
+ "/ip/proxy/cache",
340
+ "/ip/proxy/cache-contents",
341
+ "/ip/proxy/connections",
342
+ "/ip/proxy/direct",
343
+ "/ip/proxy/inserts",
344
+ "/ip/proxy/lookups",
345
+ "/ip/proxy/refreshes",
346
+ "/ip/reverse-proxy",
347
+ "/ip/route",
348
+ "/ip/service",
349
+ "/ip/service/webserver",
350
+ "/ip/settings",
351
+ "/ip/smb",
352
+ "/ip/smb/shares",
353
+ "/ip/smb/users",
354
+ "/ip/socks",
355
+ "/ip/socks/access",
356
+ "/ip/socks/connections",
357
+ "/ip/socks/users",
358
+ "/ip/socksify",
359
+ "/ip/ssh",
360
+ "/ip/ssh/known-hosts",
361
+ "/ip/tftp",
362
+ "/ip/tftp/settings",
363
+ "/ip/traffic-flow",
364
+ "/ip/traffic-flow/ipfix",
365
+ "/ip/traffic-flow/target",
366
+ "/ip/upnp",
367
+ "/ip/upnp/interfaces",
368
+ "/ip/vrf",
369
+ "/ipv6",
370
+ "/ipv6/address",
371
+ "/ipv6/dhcp-client",
372
+ "/ipv6/dhcp-client/option",
373
+ "/ipv6/dhcp-relay",
374
+ "/ipv6/dhcp-relay/option",
375
+ "/ipv6/dhcp-relay/routes",
376
+ "/ipv6/dhcp-server",
377
+ "/ipv6/dhcp-server/binding",
378
+ "/ipv6/dhcp-server/option",
379
+ "/ipv6/dhcp-server/option/sets",
380
+ "/ipv6/firewall",
381
+ "/ipv6/firewall/address-list",
382
+ "/ipv6/firewall/connection",
383
+ "/ipv6/firewall/filter",
384
+ "/ipv6/firewall/mangle",
385
+ "/ipv6/firewall/nat",
386
+ "/ipv6/firewall/raw",
387
+ "/ipv6/nd",
388
+ "/ipv6/nd/prefix",
389
+ "/ipv6/nd/prefix/default",
390
+ "/ipv6/nd/proxy",
391
+ "/ipv6/nd/settings",
392
+ "/ipv6/neighbor",
393
+ "/ipv6/pool",
394
+ "/ipv6/pool/used",
395
+ "/ipv6/route",
396
+ "/ipv6/settings",
397
+ "/log",
398
+ "/lora",
399
+ "/lora/channels",
400
+ "/lora/joineui",
401
+ "/lora/netid",
402
+ "/lora/radios",
403
+ "/lora/servers",
404
+ "/mpls",
405
+ "/mpls/forwarding-table",
406
+ "/mpls/interface",
407
+ "/mpls/ldp",
408
+ "/mpls/ldp/accept-filter",
409
+ "/mpls/ldp/advertise-filter",
410
+ "/mpls/ldp/interface",
411
+ "/mpls/ldp/local-mapping",
412
+ "/mpls/ldp/neighbor",
413
+ "/mpls/ldp/remote-mapping",
414
+ "/mpls/mangle",
415
+ "/mpls/settings",
416
+ "/mpls/traffic-eng",
417
+ "/mpls/traffic-eng/flow",
418
+ "/mpls/traffic-eng/interface",
419
+ "/mpls/traffic-eng/path",
420
+ "/mpls/traffic-eng/tunnel",
421
+ "/openflow",
422
+ "/openflow/flow",
423
+ "/openflow/group",
424
+ "/openflow/meter",
425
+ "/openflow/port",
426
+ "/port",
427
+ "/port/remote-access",
428
+ "/ppp",
429
+ "/ppp/aaa",
430
+ "/ppp/active",
431
+ "/ppp/l2tp-secret",
432
+ "/ppp/profile",
433
+ "/ppp/secret",
434
+ "/queue",
435
+ "/queue/interface",
436
+ "/queue/simple",
437
+ "/queue/tree",
438
+ "/queue/type",
439
+ "/radius",
440
+ "/radius/incoming",
441
+ "/routing",
442
+ "/routing/bfd",
443
+ "/routing/bfd/configuration",
444
+ "/routing/bfd/session",
445
+ "/routing/bgp",
446
+ "/routing/bgp/advertisements",
447
+ "/routing/bgp/connection",
448
+ "/routing/bgp/evpn",
449
+ "/routing/bgp/instance",
450
+ "/routing/bgp/session",
451
+ "/routing/bgp/template",
452
+ "/routing/bgp/vpls",
453
+ "/routing/bgp/vpn",
454
+ "/routing/fantasy",
455
+ "/routing/filter",
456
+ "/routing/filter/chain",
457
+ "/routing/filter/community-ext-list",
458
+ "/routing/filter/community-large-list",
459
+ "/routing/filter/community-list",
460
+ "/routing/filter/num-list",
461
+ "/routing/filter/rule",
462
+ "/routing/filter/select-rule",
463
+ "/routing/gmp",
464
+ "/routing/id",
465
+ "/routing/igmp-proxy",
466
+ "/routing/igmp-proxy/interface",
467
+ "/routing/igmp-proxy/mfc",
468
+ "/routing/isis",
469
+ "/routing/isis/instance",
470
+ "/routing/isis/interface",
471
+ "/routing/isis/interface-template",
472
+ "/routing/isis/lsp",
473
+ "/routing/isis/neighbor",
474
+ "/routing/nexthop",
475
+ "/routing/ospf",
476
+ "/routing/ospf/area",
477
+ "/routing/ospf/area/range",
478
+ "/routing/ospf/instance",
479
+ "/routing/ospf/interface",
480
+ "/routing/ospf/interface-template",
481
+ "/routing/ospf/lsa",
482
+ "/routing/ospf/neighbor",
483
+ "/routing/ospf/static-neighbor",
484
+ "/routing/pimsm",
485
+ "/routing/pimsm/bsr",
486
+ "/routing/pimsm/bsr/candidate",
487
+ "/routing/pimsm/bsr/rp-candidate",
488
+ "/routing/pimsm/bsr/rp-set",
489
+ "/routing/pimsm/igmp-interface-template",
490
+ "/routing/pimsm/instance",
491
+ "/routing/pimsm/interface",
492
+ "/routing/pimsm/interface-template",
493
+ "/routing/pimsm/neighbor",
494
+ "/routing/pimsm/static-rp",
495
+ "/routing/pimsm/uib-g",
496
+ "/routing/pimsm/uib-sg",
497
+ "/routing/rip",
498
+ "/routing/rip/instance",
499
+ "/routing/rip/interface",
500
+ "/routing/rip/interface-template",
501
+ "/routing/rip/keys",
502
+ "/routing/rip/neighbor",
503
+ "/routing/rip/static-neighbor",
504
+ "/routing/route",
505
+ "/routing/route/rule",
506
+ "/routing/rpki",
507
+ "/routing/rpki/session",
508
+ "/routing/rule",
509
+ "/routing/settings",
510
+ "/routing/stats",
511
+ "/routing/stats/memory",
512
+ "/routing/stats/origin",
513
+ "/routing/stats/pcap",
514
+ "/routing/stats/process",
515
+ "/routing/stats/step",
516
+ "/routing/table",
517
+ "/rsync-daemon",
518
+ "/safe-mode",
519
+ "/snmp",
520
+ "/snmp/community",
521
+ "/special-login",
522
+ "/system",
523
+ "/system/backup",
524
+ "/system/backup/cloud",
525
+ "/system/clock",
526
+ "/system/clock/manual",
527
+ "/system/console",
528
+ "/system/console/screen",
529
+ "/system/default-configuration",
530
+ "/system/default-configuration/caps-mode-script",
531
+ "/system/default-configuration/custom-script",
532
+ "/system/default-configuration/script",
533
+ "/system/device-mode",
534
+ "/system/gps",
535
+ "/system/hardware",
536
+ "/system/health",
537
+ "/system/health/settings",
538
+ "/system/history",
539
+ "/system/identity",
540
+ "/system/keymat-provider",
541
+ "/system/leds",
542
+ "/system/leds/settings",
543
+ "/system/license",
544
+ "/system/logging",
545
+ "/system/logging/action",
546
+ "/system/note",
547
+ "/system/ntp",
548
+ "/system/ntp/client",
549
+ "/system/ntp/client/servers",
550
+ "/system/ntp/key",
551
+ "/system/ntp/server",
552
+ "/system/package",
553
+ "/system/package/local-update",
554
+ "/system/package/local-update/mirror",
555
+ "/system/package/local-update/update-package-source",
556
+ "/system/package/update",
557
+ "/system/regulatory",
558
+ "/system/resource",
559
+ "/system/resource/cpu",
560
+ "/system/resource/hardware",
561
+ "/system/resource/hardware/usb-settings",
562
+ "/system/resource/irq",
563
+ "/system/resource/irq/rps",
564
+ "/system/resource/pci",
565
+ "/system/resource/usb",
566
+ "/system/resource/usb/settings",
567
+ "/system/routerboard",
568
+ "/system/routerboard/mode-button",
569
+ "/system/routerboard/reset-button",
570
+ "/system/routerboard/settings",
571
+ "/system/routerboard/usb",
572
+ "/system/routerboard/wps-button",
573
+ "/system/rtrace",
574
+ "/system/scheduler",
575
+ "/system/script",
576
+ "/system/script/environment",
577
+ "/system/script/job",
578
+ "/system/upgrade",
579
+ "/system/upgrade/mirror",
580
+ "/system/upgrade/upgrade-package-source",
581
+ "/system/ups",
582
+ "/system/watchdog",
583
+ "/task",
584
+ "/terminal",
585
+ "/tool",
586
+ "/tool/bandwidth-server",
587
+ "/tool/bandwidth-server/session",
588
+ "/tool/calea",
589
+ "/tool/e-mail",
590
+ "/tool/graphing",
591
+ "/tool/graphing/interface",
592
+ "/tool/graphing/queue",
593
+ "/tool/graphing/resource",
594
+ "/tool/mac-server",
595
+ "/tool/mac-server/mac-winbox",
596
+ "/tool/mac-server/ping",
597
+ "/tool/mac-server/sessions",
598
+ "/tool/netinstall",
599
+ "/tool/netinstall/cache",
600
+ "/tool/netinstall/devices",
601
+ "/tool/netinstall/settings",
602
+ "/tool/netwatch",
603
+ "/tool/romon",
604
+ "/tool/romon/port",
605
+ "/tool/sms",
606
+ "/tool/sms/inbox",
607
+ "/tool/sniffer",
608
+ "/tool/sniffer/connection",
609
+ "/tool/sniffer/host",
610
+ "/tool/sniffer/packet",
611
+ "/tool/sniffer/protocol",
612
+ "/tool/traffic-generator",
613
+ "/tool/traffic-generator/packet-template",
614
+ "/tool/traffic-generator/port",
615
+ "/tool/traffic-generator/raw-packet-template",
616
+ "/tool/traffic-generator/stats",
617
+ "/tool/traffic-generator/stats/latency-distribution",
618
+ "/tool/traffic-generator/stats/port",
619
+ "/tool/traffic-generator/stats/raw",
620
+ "/tool/traffic-generator/stats/stream",
621
+ "/tool/traffic-generator/stream",
622
+ "/tool/traffic-monitor",
623
+ "/tr069-client",
624
+ "/user",
625
+ "/user-manager",
626
+ "/user-manager/advanced",
627
+ "/user-manager/attribute",
628
+ "/user-manager/database",
629
+ "/user-manager/limitation",
630
+ "/user-manager/payment",
631
+ "/user-manager/profile",
632
+ "/user-manager/profile-limitation",
633
+ "/user-manager/router",
634
+ "/user-manager/session",
635
+ "/user-manager/user",
636
+ "/user-manager/user-profile",
637
+ "/user-manager/user/group",
638
+ "/user/aaa",
639
+ "/user/active",
640
+ "/user/group",
641
+ "/user/settings",
642
+ "/user/ssh-keys",
643
+ "/user/ssh-keys/private",
644
+ "/zerotier",
645
+ "/zerotier/controller",
646
+ "/zerotier/controller/member",
647
+ "/zerotier/interface",
648
+ "/zerotier/peer",
649
+ "/zerotier/peer/hint",
650
+ ]);
651
+
652
+ /**
653
+ * Is this token sequence a known RouterOS menu?
654
+ *
655
+ * Takes the path SEGMENTS rather than raw text so callers pass what they
656
+ * already parsed — `describeStatement`'s run, say — instead of re-splitting a
657
+ * statement and having to re-derive which spelling (`/ip/address` or
658
+ * `/ip address`) it used. Both spellings reduce to the same segments, which is
659
+ * the whole reason this reads segments.
660
+ *
661
+ * Empty input is not a menu: the bare `/` and `..` forms are decided by their
662
+ * own rule, and answering `true` here would let an empty run fall into a menu
663
+ * verdict by accident.
664
+ */
665
+ export function isMenuPath(segments: readonly string[]): boolean {
666
+ if (segments.length === 0) return false;
667
+ return MENU_PATHS.has(`/${segments.join("/").toLowerCase()}`);
668
+ }