@intentius/chant-lexicon-grafana 0.98.0 → 0.100.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 (532) hide show
  1. package/README.md +24 -8
  2. package/dist/actions/grafana.d.ts +24 -0
  3. package/dist/actions/grafana.d.ts.map +1 -0
  4. package/dist/actions/index.d.ts +2 -0
  5. package/dist/actions/index.d.ts.map +1 -0
  6. package/dist/alerting-build.d.ts +128 -0
  7. package/dist/alerting-build.d.ts.map +1 -0
  8. package/dist/alerting.d.ts +273 -0
  9. package/dist/alerting.d.ts.map +1 -0
  10. package/dist/annotations.d.ts +61 -0
  11. package/dist/annotations.d.ts.map +1 -0
  12. package/dist/api/apply.d.ts +160 -0
  13. package/dist/api/apply.d.ts.map +1 -0
  14. package/dist/api/bind.d.ts +32 -0
  15. package/dist/api/bind.d.ts.map +1 -0
  16. package/dist/api/client.d.ts +76 -0
  17. package/dist/api/client.d.ts.map +1 -0
  18. package/dist/api/converge.d.ts +33 -0
  19. package/dist/api/converge.d.ts.map +1 -0
  20. package/dist/api/dashboards.d.ts +102 -0
  21. package/dist/api/dashboards.d.ts.map +1 -0
  22. package/dist/api/datasources.d.ts +26 -0
  23. package/dist/api/datasources.d.ts.map +1 -0
  24. package/dist/api/fake-grafana-writes.d.ts +41 -0
  25. package/dist/api/fake-grafana-writes.d.ts.map +1 -0
  26. package/dist/api/fake-grafana.d.ts +63 -0
  27. package/dist/api/fake-grafana.d.ts.map +1 -0
  28. package/dist/api/folders.d.ts +146 -0
  29. package/dist/api/folders.d.ts.map +1 -0
  30. package/dist/api/library-panels.d.ts +52 -0
  31. package/dist/api/library-panels.d.ts.map +1 -0
  32. package/dist/build.d.ts +55 -6
  33. package/dist/build.d.ts.map +1 -1
  34. package/dist/catalog.d.ts +1 -1
  35. package/dist/catalog.d.ts.map +1 -1
  36. package/dist/codegen/docs.d.ts.map +1 -1
  37. package/dist/codegen/generate.d.ts +7 -1
  38. package/dist/codegen/generate.d.ts.map +1 -1
  39. package/dist/codegen/schema-types.d.ts +3 -3
  40. package/dist/codegen/schema-types.d.ts.map +1 -1
  41. package/dist/composites/agent-dashboard.d.ts.map +1 -1
  42. package/dist/composites/catalog.d.ts.map +1 -1
  43. package/dist/composites/index.d.ts +4 -2
  44. package/dist/composites/index.d.ts.map +1 -1
  45. package/dist/composites/red-dashboard.d.ts +21 -2
  46. package/dist/composites/red-dashboard.d.ts.map +1 -1
  47. package/dist/composites/shared.d.ts +11 -3
  48. package/dist/composites/shared.d.ts.map +1 -1
  49. package/dist/composites/slo-alert-rules.d.ts +92 -0
  50. package/dist/composites/slo-alert-rules.d.ts.map +1 -0
  51. package/dist/config.d.ts +111 -0
  52. package/dist/config.d.ts.map +1 -0
  53. package/dist/contact-point-secrets.d.ts +17 -0
  54. package/dist/contact-point-secrets.d.ts.map +1 -0
  55. package/dist/dashboard.d.ts +51 -9
  56. package/dist/dashboard.d.ts.map +1 -1
  57. package/dist/datasource-refs.d.ts +99 -0
  58. package/dist/datasource-refs.d.ts.map +1 -0
  59. package/dist/datasource-settings.d.ts +834 -0
  60. package/dist/datasource-settings.d.ts.map +1 -0
  61. package/dist/datasource.d.ts +82 -11
  62. package/dist/datasource.d.ts.map +1 -1
  63. package/dist/deep-observe-hooks.d.ts +64 -0
  64. package/dist/deep-observe-hooks.d.ts.map +1 -0
  65. package/dist/deep-observe.d.ts +47 -0
  66. package/dist/deep-observe.d.ts.map +1 -0
  67. package/dist/describe-resources.d.ts +50 -0
  68. package/dist/describe-resources.d.ts.map +1 -0
  69. package/dist/detect.d.ts +32 -3
  70. package/dist/detect.d.ts.map +1 -1
  71. package/dist/export-resources.d.ts +38 -0
  72. package/dist/export-resources.d.ts.map +1 -0
  73. package/dist/folder.d.ts +68 -0
  74. package/dist/folder.d.ts.map +1 -0
  75. package/dist/import/alerting.d.ts +40 -0
  76. package/dist/import/alerting.d.ts.map +1 -0
  77. package/dist/import/edits.d.ts +47 -0
  78. package/dist/import/edits.d.ts.map +1 -0
  79. package/dist/import/embedded.d.ts +14 -0
  80. package/dist/import/embedded.d.ts.map +1 -0
  81. package/dist/import/generator.d.ts +60 -0
  82. package/dist/import/generator.d.ts.map +1 -0
  83. package/dist/import/live-export.d.ts +108 -0
  84. package/dist/import/live-export.d.ts.map +1 -0
  85. package/dist/import/mappings.d.ts +89 -0
  86. package/dist/import/mappings.d.ts.map +1 -0
  87. package/dist/import/model.d.ts +105 -0
  88. package/dist/import/model.d.ts.map +1 -0
  89. package/dist/import/normalize-alerting.d.ts +26 -0
  90. package/dist/import/normalize-alerting.d.ts.map +1 -0
  91. package/dist/import/normalize.d.ts +74 -0
  92. package/dist/import/normalize.d.ts.map +1 -0
  93. package/dist/import/parser.d.ts +125 -0
  94. package/dist/import/parser.d.ts.map +1 -0
  95. package/dist/import/report.d.ts +26 -0
  96. package/dist/import/report.d.ts.map +1 -0
  97. package/dist/import/testdata/fixtures.d.ts +41 -0
  98. package/dist/import/testdata/fixtures.d.ts.map +1 -0
  99. package/dist/import/v2.d.ts +73 -0
  100. package/dist/import/v2.d.ts.map +1 -0
  101. package/dist/index.d.ts +31 -12
  102. package/dist/index.d.ts.map +1 -1
  103. package/dist/init-templates.d.ts +27 -0
  104. package/dist/init-templates.d.ts.map +1 -0
  105. package/dist/integrity.json +22 -12
  106. package/dist/k8s.d.ts +107 -0
  107. package/dist/k8s.d.ts.map +1 -0
  108. package/dist/lint/audit-catalog.d.ts +2 -1
  109. package/dist/lint/audit-catalog.d.ts.map +1 -1
  110. package/dist/lint/post-synth/graf101.d.ts +2 -2
  111. package/dist/lint/post-synth/graf102.d.ts +1 -1
  112. package/dist/lint/post-synth/graf104.d.ts +2 -2
  113. package/dist/lint/post-synth/graf106.d.ts +2 -2
  114. package/dist/lint/post-synth/graf107.d.ts +1 -1
  115. package/dist/lint/post-synth/graf108.d.ts +8 -0
  116. package/dist/lint/post-synth/graf108.d.ts.map +1 -0
  117. package/dist/lint/post-synth/graf109.d.ts +8 -0
  118. package/dist/lint/post-synth/graf109.d.ts.map +1 -0
  119. package/dist/lint/post-synth/graf110.d.ts +8 -0
  120. package/dist/lint/post-synth/graf110.d.ts.map +1 -0
  121. package/dist/lint/post-synth/graf111.d.ts +8 -0
  122. package/dist/lint/post-synth/graf111.d.ts.map +1 -0
  123. package/dist/lint/post-synth/graf112.d.ts +8 -0
  124. package/dist/lint/post-synth/graf112.d.ts.map +1 -0
  125. package/dist/lint/post-synth/graf113.d.ts +8 -0
  126. package/dist/lint/post-synth/graf113.d.ts.map +1 -0
  127. package/dist/lint/post-synth/graf114.d.ts +8 -0
  128. package/dist/lint/post-synth/graf114.d.ts.map +1 -0
  129. package/dist/lint/post-synth/graf115.d.ts +8 -0
  130. package/dist/lint/post-synth/graf115.d.ts.map +1 -0
  131. package/dist/lint/post-synth/grafana-helpers.d.ts +7 -5
  132. package/dist/lint/post-synth/grafana-helpers.d.ts.map +1 -1
  133. package/dist/lint/post-synth/index.d.ts.map +1 -1
  134. package/dist/lint/rules/literal-secret.d.ts +7 -3
  135. package/dist/lint/rules/literal-secret.d.ts.map +1 -1
  136. package/dist/lsp/hover.d.ts.map +1 -1
  137. package/dist/manifest.json +1 -1
  138. package/dist/members.d.ts +27 -0
  139. package/dist/members.d.ts.map +1 -0
  140. package/dist/meta.json +205 -0
  141. package/dist/okf/index.md +53 -4
  142. package/dist/okf/rules/GRAF002.md +3 -2
  143. package/dist/okf/rules/GRAF101.md +3 -2
  144. package/dist/okf/rules/GRAF102.md +1 -0
  145. package/dist/okf/rules/GRAF104.md +2 -2
  146. package/dist/okf/rules/GRAF106.md +2 -2
  147. package/dist/okf/rules/GRAF108.md +11 -0
  148. package/dist/okf/rules/GRAF109.md +15 -0
  149. package/dist/okf/rules/GRAF110.md +11 -0
  150. package/dist/okf/rules/GRAF111.md +11 -0
  151. package/dist/okf/rules/GRAF112.md +16 -0
  152. package/dist/okf/rules/GRAF113.md +16 -0
  153. package/dist/okf/rules/GRAF114.md +11 -0
  154. package/dist/okf/rules/GRAF115.md +11 -0
  155. package/dist/okf/types/AdhocVariable.md +9 -0
  156. package/dist/okf/types/AlertListPanel.md +9 -0
  157. package/dist/okf/types/AlertQuery.md +9 -0
  158. package/dist/okf/types/AlertRule.md +9 -0
  159. package/dist/okf/types/AlertRuleGroup.md +9 -0
  160. package/dist/okf/types/AzureMonitorQuery.md +9 -0
  161. package/dist/okf/types/BarChartPanel.md +9 -0
  162. package/dist/okf/types/BarGaugePanel.md +9 -0
  163. package/dist/okf/types/BigQueryQuery.md +9 -0
  164. package/dist/okf/types/CanvasPanel.md +9 -0
  165. package/dist/okf/types/ClassicConditionsExpression.md +9 -0
  166. package/dist/okf/types/CloudMonitoringQuery.md +9 -0
  167. package/dist/okf/types/CloudWatchQuery.md +9 -0
  168. package/dist/okf/types/ContactPoint.md +14 -0
  169. package/dist/okf/types/Dashboard.md +2 -1
  170. package/dist/okf/types/Datasource.md +3 -2
  171. package/dist/okf/types/DatasourceProvisioning.md +9 -0
  172. package/dist/okf/types/ElasticsearchQuery.md +9 -0
  173. package/dist/okf/types/ExternalDatasource.md +15 -0
  174. package/dist/okf/types/FlameGraphPanel.md +9 -0
  175. package/dist/okf/types/Folder.md +9 -0
  176. package/dist/okf/types/GeomapPanel.md +9 -0
  177. package/dist/okf/types/GroupByVariable.md +9 -0
  178. package/dist/okf/types/HistogramPanel.md +9 -0
  179. package/dist/okf/types/MSSQLQuery.md +9 -0
  180. package/dist/okf/types/MathExpression.md +9 -0
  181. package/dist/okf/types/MuteTiming.md +13 -0
  182. package/dist/okf/types/MySQLQuery.md +9 -0
  183. package/dist/okf/types/NodeGraphPanel.md +9 -0
  184. package/dist/okf/types/NotificationPolicy.md +9 -0
  185. package/dist/okf/types/NotificationTemplate.md +9 -0
  186. package/dist/okf/types/PieChartPanel.md +9 -0
  187. package/dist/okf/types/PostgresQuery.md +9 -0
  188. package/dist/okf/types/PyroscopeQuery.md +9 -0
  189. package/dist/okf/types/ReduceExpression.md +9 -0
  190. package/dist/okf/types/ResampleExpression.md +9 -0
  191. package/dist/okf/types/SqlExpression.md +9 -0
  192. package/dist/okf/types/StateTimelinePanel.md +9 -0
  193. package/dist/okf/types/StatusHistoryPanel.md +9 -0
  194. package/dist/okf/types/SwitchVariable.md +9 -0
  195. package/dist/okf/types/ThresholdExpression.md +9 -0
  196. package/dist/okf/types/TrendPanel.md +9 -0
  197. package/dist/okf/types/XYChartPanel.md +9 -0
  198. package/dist/op/activities/grafana-apply.d.ts +86 -0
  199. package/dist/op/activities/grafana-apply.d.ts.map +1 -0
  200. package/dist/op/activities/index.d.ts +9 -0
  201. package/dist/op/activities/index.d.ts.map +1 -0
  202. package/dist/op/builders.d.ts +24 -0
  203. package/dist/op/builders.d.ts.map +1 -0
  204. package/dist/ownership.d.ts +78 -0
  205. package/dist/ownership.d.ts.map +1 -0
  206. package/dist/panel-options.d.ts +65 -0
  207. package/dist/panel-options.d.ts.map +1 -0
  208. package/dist/panels.d.ts +46 -9
  209. package/dist/panels.d.ts.map +1 -1
  210. package/dist/pin.d.ts +29 -7
  211. package/dist/pin.d.ts.map +1 -1
  212. package/dist/plugin.d.ts.map +1 -1
  213. package/dist/promql-check.d.ts +51 -0
  214. package/dist/promql-check.d.ts.map +1 -0
  215. package/dist/query-models.d.ts +95 -0
  216. package/dist/query-models.d.ts.map +1 -0
  217. package/dist/query.d.ts +116 -18
  218. package/dist/query.d.ts.map +1 -1
  219. package/dist/rules/graf101.ts +3 -3
  220. package/dist/rules/graf102.ts +1 -1
  221. package/dist/rules/graf104.ts +3 -3
  222. package/dist/rules/graf106.ts +3 -3
  223. package/dist/rules/graf107.ts +1 -1
  224. package/dist/rules/graf108.ts +17 -0
  225. package/dist/rules/graf109.ts +17 -0
  226. package/dist/rules/graf110.ts +17 -0
  227. package/dist/rules/graf111.ts +17 -0
  228. package/dist/rules/graf112.ts +17 -0
  229. package/dist/rules/graf113.ts +17 -0
  230. package/dist/rules/graf114.ts +17 -0
  231. package/dist/rules/graf115.ts +17 -0
  232. package/dist/rules/grafana-helpers.ts +27 -10
  233. package/dist/rules/literal-secret.ts +60 -6
  234. package/dist/schema/azuremonitor.gen.d.ts +354 -0
  235. package/dist/schema/azuremonitor.gen.d.ts.map +1 -0
  236. package/dist/schema/barchart.gen.d.ts +198 -0
  237. package/dist/schema/barchart.gen.d.ts.map +1 -0
  238. package/dist/schema/bargauge.gen.d.ts +97 -0
  239. package/dist/schema/bargauge.gen.d.ts.map +1 -0
  240. package/dist/schema/bigquery.gen.d.ts +93 -0
  241. package/dist/schema/bigquery.gen.d.ts.map +1 -0
  242. package/dist/schema/canvas.gen.d.ts +152 -0
  243. package/dist/schema/canvas.gen.d.ts.map +1 -0
  244. package/dist/schema/cloudwatch.gen.d.ts +394 -0
  245. package/dist/schema/cloudwatch.gen.d.ts.map +1 -0
  246. package/dist/schema/dashboard.gen.d.ts +196 -21
  247. package/dist/schema/dashboard.gen.d.ts.map +1 -1
  248. package/dist/schema/elasticsearch.gen.d.ts +444 -0
  249. package/dist/schema/elasticsearch.gen.d.ts.map +1 -0
  250. package/dist/schema/expr.gen.d.ts +606 -0
  251. package/dist/schema/expr.gen.d.ts.map +1 -0
  252. package/dist/schema/gauge.gen.d.ts.map +1 -1
  253. package/dist/schema/geomap.gen.d.ts +100 -0
  254. package/dist/schema/geomap.gen.d.ts.map +1 -0
  255. package/dist/schema/googlecloudmonitoring.gen.d.ts +312 -0
  256. package/dist/schema/googlecloudmonitoring.gen.d.ts.map +1 -0
  257. package/dist/schema/grafanapyroscope.gen.d.ts +60 -0
  258. package/dist/schema/grafanapyroscope.gen.d.ts.map +1 -0
  259. package/dist/schema/heatmap.gen.d.ts.map +1 -1
  260. package/dist/schema/histogram.gen.d.ts +132 -0
  261. package/dist/schema/histogram.gen.d.ts.map +1 -0
  262. package/dist/schema/index.d.ts +18 -0
  263. package/dist/schema/index.d.ts.map +1 -1
  264. package/dist/schema/logs.gen.d.ts +1 -0
  265. package/dist/schema/logs.gen.d.ts.map +1 -1
  266. package/dist/schema/loki.gen.d.ts.map +1 -1
  267. package/dist/schema/nodegraph.gen.d.ts +49 -0
  268. package/dist/schema/nodegraph.gen.d.ts.map +1 -0
  269. package/dist/schema/piechart.gen.d.ts +127 -0
  270. package/dist/schema/piechart.gen.d.ts.map +1 -0
  271. package/dist/schema/prometheus.gen.d.ts.map +1 -1
  272. package/dist/schema/stat.gen.d.ts.map +1 -1
  273. package/dist/schema/statetimeline.gen.d.ts +124 -0
  274. package/dist/schema/statetimeline.gen.d.ts.map +1 -0
  275. package/dist/schema/statushistory.gen.d.ts +114 -0
  276. package/dist/schema/statushistory.gen.d.ts.map +1 -0
  277. package/dist/schema/table.gen.d.ts +35 -3
  278. package/dist/schema/table.gen.d.ts.map +1 -1
  279. package/dist/schema/tempo.gen.d.ts.map +1 -1
  280. package/dist/schema/text.gen.d.ts.map +1 -1
  281. package/dist/schema/timeseries.gen.d.ts +5 -1
  282. package/dist/schema/timeseries.gen.d.ts.map +1 -1
  283. package/dist/schema/trend.gen.d.ts +180 -0
  284. package/dist/schema/trend.gen.d.ts.map +1 -0
  285. package/dist/schema/xychart.gen.d.ts +145 -0
  286. package/dist/schema/xychart.gen.d.ts.map +1 -0
  287. package/dist/schema-validate.d.ts +39 -4
  288. package/dist/schema-validate.d.ts.map +1 -1
  289. package/dist/serializer.d.ts +11 -3
  290. package/dist/serializer.d.ts.map +1 -1
  291. package/dist/skill-defs.d.ts.map +1 -1
  292. package/dist/skills/chant-grafana-alerting.md +49 -0
  293. package/dist/skills/chant-grafana-operations.md +108 -0
  294. package/dist/skills/chant-grafana-provisioning.md +3 -3
  295. package/dist/skills/chant-grafana.md +15 -8
  296. package/dist/spec/fetch-units-cli.d.ts +3 -0
  297. package/dist/spec/fetch-units-cli.d.ts.map +1 -0
  298. package/dist/spec/overlay.d.ts +43 -0
  299. package/dist/spec/overlay.d.ts.map +1 -0
  300. package/dist/spec/schemas.d.ts +21 -13
  301. package/dist/spec/schemas.d.ts.map +1 -1
  302. package/dist/spec/schemas.gen.d.ts +3 -0
  303. package/dist/spec/schemas.gen.d.ts.map +1 -0
  304. package/dist/spec/units.d.ts +35 -0
  305. package/dist/spec/units.d.ts.map +1 -0
  306. package/dist/spec/units.gen.d.ts +2 -0
  307. package/dist/spec/units.gen.d.ts.map +1 -0
  308. package/dist/transformations.d.ts +459 -0
  309. package/dist/transformations.d.ts.map +1 -0
  310. package/dist/util.d.ts +6 -0
  311. package/dist/util.d.ts.map +1 -1
  312. package/dist/validate-alerting.d.ts +65 -0
  313. package/dist/validate-alerting.d.ts.map +1 -0
  314. package/dist/validate-output.d.ts +62 -9
  315. package/dist/validate-output.d.ts.map +1 -1
  316. package/dist/validate.d.ts.map +1 -1
  317. package/dist/validation.d.ts +14 -0
  318. package/dist/validation.d.ts.map +1 -0
  319. package/dist/variables.d.ts +109 -7
  320. package/dist/variables.d.ts.map +1 -1
  321. package/package.json +12 -4
  322. package/src/actions/actions.test.ts +24 -0
  323. package/src/actions/grafana.ts +40 -0
  324. package/src/actions/index.ts +1 -0
  325. package/src/alerting-build.ts +376 -0
  326. package/src/alerting.e2e.test.ts +212 -0
  327. package/src/alerting.test.ts +272 -0
  328. package/src/alerting.ts +435 -0
  329. package/src/annotations.ts +84 -0
  330. package/src/api/apply.test.ts +256 -0
  331. package/src/api/apply.ts +394 -0
  332. package/src/api/bind.ts +58 -0
  333. package/src/api/client.ts +148 -0
  334. package/src/api/converge.ts +63 -0
  335. package/src/api/dashboards.ts +247 -0
  336. package/src/api/datasources.ts +33 -0
  337. package/src/api/fake-grafana-writes.ts +201 -0
  338. package/src/api/fake-grafana.ts +190 -0
  339. package/src/api/folders.ts +339 -0
  340. package/src/api/library-panels.ts +101 -0
  341. package/src/build.test.ts +351 -10
  342. package/src/build.ts +294 -55
  343. package/src/catalog.ts +104 -2
  344. package/src/codegen/docs.ts +50 -10
  345. package/src/codegen/generate.ts +27 -1
  346. package/src/codegen/schema-types.ts +16 -6
  347. package/src/composites/agent-dashboard.ts +6 -3
  348. package/src/composites/catalog.test.ts +2 -2
  349. package/src/composites/catalog.ts +82 -0
  350. package/src/composites/composites.test.ts +73 -9
  351. package/src/composites/index.ts +4 -2
  352. package/src/composites/queries.e2e.test.ts +374 -0
  353. package/src/composites/red-dashboard.ts +83 -12
  354. package/src/composites/shared.ts +14 -2
  355. package/src/composites/slo-alert-rules.ts +149 -0
  356. package/src/config.test.ts +61 -0
  357. package/src/config.ts +138 -0
  358. package/src/contact-point-secrets.ts +63 -0
  359. package/src/dashboard.ts +68 -9
  360. package/src/datasource-refs.test.ts +56 -0
  361. package/src/datasource-refs.ts +213 -0
  362. package/src/datasource-settings.test.ts +106 -0
  363. package/src/datasource-settings.ts +941 -0
  364. package/src/datasource.ts +123 -11
  365. package/src/deep-observe-hooks.ts +267 -0
  366. package/src/deep-observe.test.ts +311 -0
  367. package/src/deep-observe.ts +187 -0
  368. package/src/describe-resources.test.ts +271 -0
  369. package/src/describe-resources.ts +244 -0
  370. package/src/detect.ts +82 -5
  371. package/src/export-resources.test.ts +129 -0
  372. package/src/export-resources.ts +84 -0
  373. package/src/folder.ts +118 -0
  374. package/src/generated/lexicon-grafana.json +205 -0
  375. package/src/import/alerting-roundtrip.test.ts +161 -0
  376. package/src/import/alerting.ts +500 -0
  377. package/src/import/edits.ts +95 -0
  378. package/src/import/embedded.test.ts +45 -0
  379. package/src/import/embedded.ts +47 -0
  380. package/src/import/generated-types.e2e.test.ts +130 -0
  381. package/src/import/generator.test.ts +210 -0
  382. package/src/import/generator.ts +463 -0
  383. package/src/import/live-export.ts +264 -0
  384. package/src/import/mappings.ts +336 -0
  385. package/src/import/model.ts +117 -0
  386. package/src/import/normalize-alerting.ts +101 -0
  387. package/src/import/normalize.test.ts +117 -0
  388. package/src/import/normalize.ts +393 -0
  389. package/src/import/parser.test.ts +516 -0
  390. package/src/import/parser.ts +1387 -0
  391. package/src/import/report.ts +62 -0
  392. package/src/import/roundtrip.test.ts +563 -0
  393. package/src/import/testdata/fixtures.ts +137 -0
  394. package/src/import/v2.test.ts +292 -0
  395. package/src/import/v2.ts +804 -0
  396. package/src/import.e2e.test.ts +31 -84
  397. package/src/import.test.ts +9 -3
  398. package/src/index.ts +308 -14
  399. package/src/init-templates.test.ts +74 -0
  400. package/src/init-templates.ts +349 -0
  401. package/src/k8s.test.ts +98 -0
  402. package/src/k8s.ts +197 -0
  403. package/src/lint/audit-catalog.ts +68 -3
  404. package/src/lint/core-lint.test.ts +43 -0
  405. package/src/lint/post-synth/graf101.ts +3 -3
  406. package/src/lint/post-synth/graf102.ts +1 -1
  407. package/src/lint/post-synth/graf104.ts +3 -3
  408. package/src/lint/post-synth/graf106.ts +3 -3
  409. package/src/lint/post-synth/graf107.ts +1 -1
  410. package/src/lint/post-synth/graf108.ts +17 -0
  411. package/src/lint/post-synth/graf109.ts +17 -0
  412. package/src/lint/post-synth/graf110.ts +17 -0
  413. package/src/lint/post-synth/graf111.ts +17 -0
  414. package/src/lint/post-synth/graf112.ts +17 -0
  415. package/src/lint/post-synth/graf113.ts +17 -0
  416. package/src/lint/post-synth/graf114.ts +17 -0
  417. package/src/lint/post-synth/graf115.ts +17 -0
  418. package/src/lint/post-synth/grafana-helpers.ts +27 -10
  419. package/src/lint/post-synth/index.ts +16 -0
  420. package/src/lint/post-synth/post-synth.test.ts +333 -12
  421. package/src/lint/rules/literal-secret.ts +60 -6
  422. package/src/lint/rules/rules.test.ts +27 -0
  423. package/src/load-cost.test.ts +35 -0
  424. package/src/lsp/completions.test.ts +5 -0
  425. package/src/lsp/hover.test.ts +7 -0
  426. package/src/lsp/hover.ts +8 -1
  427. package/src/members.ts +68 -0
  428. package/src/observe.e2e.test.ts +255 -0
  429. package/src/op/activities/grafana-apply.e2e.test.ts +184 -0
  430. package/src/op/activities/grafana-apply.test.ts +243 -0
  431. package/src/op/activities/grafana-apply.ts +197 -0
  432. package/src/op/activities/index.ts +8 -0
  433. package/src/op/builders.test.ts +40 -0
  434. package/src/op/builders.ts +34 -0
  435. package/src/ownership.ts +122 -0
  436. package/src/panel-options.ts +66 -0
  437. package/src/panels.test.ts +53 -0
  438. package/src/panels.ts +148 -10
  439. package/src/pin.ts +69 -6
  440. package/src/plugin.test.ts +12 -2
  441. package/src/plugin.ts +75 -0
  442. package/src/promql-check.test.ts +108 -0
  443. package/src/promql-check.ts +193 -0
  444. package/src/query-models.ts +94 -0
  445. package/src/query.test.ts +166 -0
  446. package/src/query.ts +190 -20
  447. package/src/schema/azuremonitor.gen.ts +381 -0
  448. package/src/schema/barchart.gen.ts +221 -0
  449. package/src/schema/bargauge.gen.ts +111 -0
  450. package/src/schema/bigquery.gen.ts +110 -0
  451. package/src/schema/canvas.gen.ts +176 -0
  452. package/src/schema/cloudwatch.gen.ts +423 -0
  453. package/src/schema/dashboard.gen.ts +206 -22
  454. package/src/schema/elasticsearch.gen.ts +508 -0
  455. package/src/schema/expr.gen.ts +618 -0
  456. package/src/schema/gauge.gen.ts +2 -1
  457. package/src/schema/geomap.gen.ts +112 -0
  458. package/src/schema/googlecloudmonitoring.gen.ts +330 -0
  459. package/src/schema/grafanapyroscope.gen.ts +66 -0
  460. package/src/schema/heatmap.gen.ts +2 -1
  461. package/src/schema/histogram.gen.ts +151 -0
  462. package/src/schema/index.ts +18 -0
  463. package/src/schema/logs.gen.ts +3 -1
  464. package/src/schema/loki.gen.ts +2 -1
  465. package/src/schema/nodegraph.gen.ts +58 -0
  466. package/src/schema/piechart.gen.ts +146 -0
  467. package/src/schema/prometheus.gen.ts +2 -1
  468. package/src/schema/stat.gen.ts +2 -1
  469. package/src/schema/statetimeline.gen.ts +143 -0
  470. package/src/schema/statushistory.gen.ts +132 -0
  471. package/src/schema/table.gen.ts +41 -4
  472. package/src/schema/tempo.gen.ts +2 -1
  473. package/src/schema/text.gen.ts +2 -1
  474. package/src/schema/timeseries.gen.ts +7 -2
  475. package/src/schema/trend.gen.ts +208 -0
  476. package/src/schema/xychart.gen.ts +167 -0
  477. package/src/schema-overlay.test.ts +282 -0
  478. package/src/schema-validate.ts +199 -57
  479. package/src/schema.test.ts +4 -2
  480. package/src/serializer.test.ts +13 -1
  481. package/src/serializer.ts +11 -3
  482. package/src/skill-defs.ts +34 -0
  483. package/src/skills/chant-grafana-alerting.md +49 -0
  484. package/src/skills/chant-grafana-operations.md +108 -0
  485. package/src/skills/chant-grafana-provisioning.md +3 -3
  486. package/src/skills/chant-grafana.md +15 -8
  487. package/src/spec/fetch-cli.ts +3 -3
  488. package/src/spec/fetch-units-cli.ts +37 -0
  489. package/src/spec/overlay/canvas.overlay.json +142 -0
  490. package/src/spec/overlay/dashboard.overlay.json +378 -0
  491. package/src/spec/overlay/expr.overlay.json +14 -0
  492. package/src/spec/overlay/geomap.overlay.json +35 -0
  493. package/src/spec/overlay/logs.overlay.json +14 -0
  494. package/src/spec/overlay/nodegraph.overlay.json +31 -0
  495. package/src/spec/overlay/piechart.overlay.json +17 -0
  496. package/src/spec/overlay/table.overlay.json +103 -0
  497. package/src/spec/overlay/timeseries.overlay.json +21 -0
  498. package/src/spec/overlay/trend.overlay.json +17 -0
  499. package/src/spec/overlay/xychart.overlay.json +16 -0
  500. package/src/spec/overlay.ts +105 -0
  501. package/src/spec/schemas/azuremonitor.jsonschema.json +679 -0
  502. package/src/spec/schemas/barchart.jsonschema.json +419 -0
  503. package/src/spec/schemas/bargauge.jsonschema.json +224 -0
  504. package/src/spec/schemas/bigquery.jsonschema.json +290 -0
  505. package/src/spec/schemas/canvas.jsonschema.json +356 -0
  506. package/src/spec/schemas/cloudwatch.jsonschema.json +721 -0
  507. package/src/spec/schemas/dashboardv2.jsonschema.json +3387 -0
  508. package/src/spec/schemas/elasticsearch.jsonschema.json +1695 -0
  509. package/src/spec/schemas/expr.jsonschema.json +987 -0
  510. package/src/spec/schemas/geomap.jsonschema.json +220 -0
  511. package/src/spec/schemas/googlecloudmonitoring.jsonschema.json +488 -0
  512. package/src/spec/schemas/grafanapyroscope.jsonschema.json +93 -0
  513. package/src/spec/schemas/histogram.jsonschema.json +308 -0
  514. package/src/spec/schemas/nodegraph.jsonschema.json +77 -0
  515. package/src/spec/schemas/piechart.jsonschema.json +275 -0
  516. package/src/spec/schemas/statetimeline.jsonschema.json +324 -0
  517. package/src/spec/schemas/statushistory.jsonschema.json +292 -0
  518. package/src/spec/schemas/trend.jsonschema.json +449 -0
  519. package/src/spec/schemas/xychart.jsonschema.json +428 -0
  520. package/src/spec/schemas.gen.ts +40 -0
  521. package/src/spec/schemas.ts +30 -16
  522. package/src/spec/units.gen.ts +281 -0
  523. package/src/spec/units.ts +77 -0
  524. package/src/transformations.test.ts +65 -0
  525. package/src/transformations.ts +574 -0
  526. package/src/util.ts +8 -0
  527. package/src/validate-alerting.test.ts +255 -0
  528. package/src/validate-alerting.ts +430 -0
  529. package/src/validate-output.ts +427 -104
  530. package/src/validate.ts +28 -0
  531. package/src/validation.ts +27 -0
  532. package/src/variables.ts +120 -8
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Hand-written option types for the built-in panels that have no schema.
3
+ *
4
+ * The alert list and flame graph panels define their options in TypeScript
5
+ * inside Grafana's frontend, with no CUE kind, so foundation-sdk publishes
6
+ * no JSON Schema for them and `npm run generate` has nothing to read. The
7
+ * types here follow Grafana's source at v13.2.2, cited per type. GRAF107
8
+ * checks these panels' envelope (the dashboard schema's `Panel`) but not
9
+ * their `options`; the traces panel is in the same position and keeps
10
+ * untyped options.
11
+ */
12
+
13
+ import type { ThresholdsConfig, ValueMapping } from "./schema/dashboard.gen";
14
+
15
+ /**
16
+ * How the alert list orders rules: `SortOrder` in
17
+ * public/app/plugins/panel/alertlist/types.ts:4-10 (a numeric enum starting at 1).
18
+ * 1 alphabetical ascending, 2 descending, 3 by importance, 4 time ascending, 5 time descending.
19
+ */
20
+ export type AlertListSortOrder = 1 | 2 | 3 | 4 | 5;
21
+
22
+ /** Which rule states the alert list shows: `StateFilter`, public/app/plugins/panel/alertlist/types.ts:22-30. */
23
+ export interface AlertListStateFilter {
24
+ firing: boolean;
25
+ pending: boolean;
26
+ /** Kept for dashboards saved before 9.x. */
27
+ inactive: boolean;
28
+ recovering: boolean;
29
+ noData: boolean;
30
+ normal: boolean;
31
+ error: boolean;
32
+ }
33
+
34
+ /**
35
+ * The alert list panel's options: `UnifiedAlertListOptions`,
36
+ * public/app/plugins/panel/alertlist/types.ts:32-49 at v13.2.2. Defaults are in
37
+ * public/app/plugins/panel/alertlist/module.tsx.
38
+ */
39
+ export interface AlertListOptions {
40
+ maxItems: number;
41
+ sortOrder: AlertListSortOrder;
42
+ /** Only rules from the dashboard the panel is on. */
43
+ dashboardAlerts: boolean;
44
+ groupMode: "default" | "custom";
45
+ groupBy: string[];
46
+ alertName: string;
47
+ showInstances: boolean;
48
+ /** Only rules in this folder; null for any. */
49
+ folder: { uid: string; title: string } | null;
50
+ stateFilter: AlertListStateFilter;
51
+ alertInstanceLabelFilter: string;
52
+ /** The rule source's datasource name, or null for all. */
53
+ datasource: string | null;
54
+ viewMode: "list" | "stat";
55
+ showInactiveAlerts: boolean;
56
+ /** `BigValueColorMode`, packages/grafana-ui/src/components/BigValue/BigValueTypes.ts:8-13. */
57
+ statColorMode: "background" | "background_solid" | "none" | "value";
58
+ statThresholds: ThresholdsConfig;
59
+ statValueMappings: ValueMapping[];
60
+ }
61
+
62
+ /** The flame graph panel's options: `Options`, public/app/plugins/panel/flamegraph/types.ts:1-3 at v13.2.2. */
63
+ export interface FlameGraphOptions {
64
+ /** Hide the top table and show only the flame graph. */
65
+ showFlameGraphOnly: boolean;
66
+ }
@@ -0,0 +1,53 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import * as panels from "./panels";
3
+ import { Dashboard } from "./dashboard";
4
+ import { renderDashboard } from "./build";
5
+ import { validateDashboardSchema } from "./schema-validate";
6
+ import { SCHEMA_NAMES } from "./pin";
7
+ import { registeredQueries } from "./query";
8
+
9
+ const builtins = panels.registeredPanels().filter((d) => d.builtin);
10
+
11
+ describe("built-in panels", () => {
12
+ test("every panel type Grafana ships with a schema at the pin has a class", () => {
13
+ const querySchemas = new Set<string>(registeredQueries().flatMap((d) => (d.schema ? [d.schema] : [])));
14
+ const panelSchemas = SCHEMA_NAMES.filter((n) => n !== "dashboard" && n !== "expr" && !querySchemas.has(n));
15
+ expect(builtins.map((d) => d.schema).filter(Boolean).sort()).toEqual([...panelSchemas].sort());
16
+ });
17
+
18
+ test("the panels with no upstream schema are typed by hand and not validated beyond the Panel envelope", () => {
19
+ expect(builtins.filter((d) => !d.schema).map((d) => d.type).sort()).toEqual(["alertlist", "flamegraph", "traces"]);
20
+ });
21
+
22
+ test("the node graph keeps Grafana's camelCase id; a plugin chant does not ship may not", () => {
23
+ expect(panels.NodeGraphPanel.definition.type).toBe("nodeGraph");
24
+ expect(() => panels.definePanel()({ type: "myGraph", className: "MyGraph", defaultSize: { w: 1, h: 1 } })).toThrow(/not a panel plugin id/);
25
+ });
26
+
27
+ test.each(builtins.map((d) => [d.className, d] as const))("%s renders a dashboard GRAF107 accepts", (_name, def) => {
28
+ const Cls = (panels as unknown as Record<string, panels.PanelClass>)[def.className];
29
+ const json = renderDashboard(new Dashboard({ title: def.className, panels: [new Cls({ title: "p" })] }));
30
+ expect(json.panels![0]).toMatchObject({ type: def.type, gridPos: { w: def.defaultSize.w, h: def.defaultSize.h } });
31
+ expect(validateDashboardSchema(json as unknown as Record<string, unknown>)).toEqual([]);
32
+ });
33
+
34
+ test("typed options reach the JSON, and a value the schema rejects is a GRAF107 error", () => {
35
+ const pie = new panels.PieChartPanel({ options: { pieType: "donut", sort: "desc", displayLabels: ["percent"] } });
36
+ const ok = renderDashboard(new Dashboard({ title: "Pie", panels: [pie] }));
37
+ expect((ok.panels![0] as { options?: unknown }).options).toEqual({ pieType: "donut", sort: "desc", displayLabels: ["percent"] });
38
+ expect(validateDashboardSchema(ok as unknown as Record<string, unknown>)).toEqual([]);
39
+
40
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
41
+ const bad = new panels.BarGaugePanel({ options: { displayMode: "sparkle" as any } });
42
+ const problems = validateDashboardSchema(renderDashboard(new Dashboard({ title: "Bad", panels: [bad] })) as unknown as Record<string, unknown>);
43
+ expect(problems).toEqual([expect.objectContaining({ path: "/panels/0/options/displayMode", severity: "error" })]);
44
+ });
45
+
46
+ test("the hand-typed alert list options type what Grafana writes", () => {
47
+ const list = new panels.AlertListPanel({ options: { viewMode: "stat", sortOrder: 3, stateFilter: { firing: true, error: true }, folder: null } });
48
+ expect(renderDashboard(new Dashboard({ title: "Alerts", panels: [list] })).panels![0]).toMatchObject({
49
+ type: "alertlist",
50
+ options: { viewMode: "stat", sortOrder: 3, stateFilter: { firing: true, error: true }, folder: null },
51
+ });
52
+ });
53
+ });
package/src/panels.ts CHANGED
@@ -11,8 +11,10 @@
11
11
  *
12
12
  * `gridPos` is optional. A panel without `x` and `y` is placed by the
13
13
  * dashboard: left to right in declaration order, wrapping at Grafana's
14
- * 24-column width, below the previous row of panels. A panel with both is
15
- * placed exactly there, and GRAF105 reports overlaps.
14
+ * 24-column width, below the previous row of panels, and around any cells
15
+ * already taken. A panel with both is placed exactly there and reserves its
16
+ * cells first; GRAF105 reports overlaps between explicit panels. A panel
17
+ * with only `x` or only `y` keeps that column or line.
16
18
  */
17
19
 
18
20
  import { createProperty } from "@intentius/chant/runtime";
@@ -23,7 +25,6 @@ import type { VariableEntity } from "./variables";
23
25
  import type { SchemaName } from "./pin";
24
26
  import type {
25
27
  DashboardLink,
26
- DataTransformerConfig,
27
28
  FieldConfig,
28
29
  FieldConfigSource,
29
30
  GridPos,
@@ -35,6 +36,19 @@ import type * as table from "./schema/table.gen";
35
36
  import type * as logs from "./schema/logs.gen";
36
37
  import type * as heatmap from "./schema/heatmap.gen";
37
38
  import type * as text from "./schema/text.gen";
39
+ import type * as barchart from "./schema/barchart.gen";
40
+ import type * as bargauge from "./schema/bargauge.gen";
41
+ import type * as piechart from "./schema/piechart.gen";
42
+ import type * as statetimeline from "./schema/statetimeline.gen";
43
+ import type * as statushistory from "./schema/statushistory.gen";
44
+ import type * as histogram from "./schema/histogram.gen";
45
+ import type * as nodegraph from "./schema/nodegraph.gen";
46
+ import type * as xychart from "./schema/xychart.gen";
47
+ import type * as trend from "./schema/trend.gen";
48
+ import type * as canvas from "./schema/canvas.gen";
49
+ import type * as geomap from "./schema/geomap.gen";
50
+ import type { AlertListOptions, FlameGraphOptions } from "./panel-options";
51
+ import type { Transformation } from "./transformations";
38
52
 
39
53
  /** `fieldConfig` with `defaults.custom` typed for the panel. */
40
54
  export interface PanelFieldConfig<C> {
@@ -59,7 +73,8 @@ export interface PanelProps<O = Record<string, unknown>, C = Record<string, unkn
59
73
  /** The panel plugin's own options, typed from its schema. */
60
74
  options?: DeepPartial<O>;
61
75
  fieldConfig?: PanelFieldConfig<C>;
62
- transformations?: DataTransformerConfig[];
76
+ /** Typed per transformer: `{ id: "organize", options: { ... } }`, `transformation(id, options)`, or `customTransformation()` for an id or option the types don't know. */
77
+ transformations?: Transformation[];
63
78
  links?: PanelLink[];
64
79
  /** Repeat the panel once per value of this variable. */
65
80
  repeat?: VariableEntity | string;
@@ -118,9 +133,11 @@ export function panelDefinitionFor(type: string): PanelDefinition | undefined {
118
133
  }
119
134
 
120
135
  const PLUGIN_ID = /^[a-z0-9][a-z0-9-_]*$/;
136
+ /** Core panel ids predate the lowercase rule plugin ids follow: the node graph is `nodeGraph`. */
137
+ const CORE_PLUGIN_ID = /^[A-Za-z0-9][A-Za-z0-9-_]*$/;
121
138
 
122
139
  function makePanelClass<T extends string, O, C>(def: PanelDefinition<T>): PanelClass<T, O, C> {
123
- if (!PLUGIN_ID.test(def.type)) throw new Error(`grafana: "${def.type}" is not a panel plugin id`);
140
+ if (!(def.builtin ? CORE_PLUGIN_ID : PLUGIN_ID).test(def.type)) throw new Error(`grafana: "${def.type}" is not a panel plugin id`);
124
141
  if (def.type === "row") throw new Error('grafana: "row" is not a panel; use Row');
125
142
  const existing = registry().get(def.type);
126
143
  if (existing?.builtin && !def.builtin) {
@@ -145,12 +162,12 @@ function makePanelClass<T extends string, O, C>(def: PanelDefinition<T>): PanelC
145
162
  *
146
163
  * @example
147
164
  * ```ts
148
- * interface PieOptions { pieType?: "pie" | "donut"; legend?: { showLegend?: boolean } }
165
+ * interface ClockOptions { mode?: "time" | "countdown"; clockType?: "24 hour" | "12 hour" }
149
166
  *
150
- * export const PieChartPanel = definePanel<PieOptions>()({
151
- * type: "piechart",
152
- * className: "PieChartPanel",
153
- * defaultSize: { w: 8, h: 8 },
167
+ * export const ClockPanel = definePanel<ClockOptions>()({
168
+ * type: "grafana-clock-panel",
169
+ * className: "ClockPanel",
170
+ * defaultSize: { w: 6, h: 4 },
154
171
  * });
155
172
  * ```
156
173
  */
@@ -243,6 +260,121 @@ export const TextPanel = makePanelClass<"text", text.Options, Record<string, unk
243
260
  builtin: true,
244
261
  });
245
262
 
263
+ export const BarChartPanel = makePanelClass<"barchart", barchart.Options, barchart.FieldConfig>({
264
+ type: "barchart",
265
+ className: "BarChartPanel",
266
+ description: "Bar chart: categorical values as bars, grouped or stacked",
267
+ defaultSize: { w: 12, h: 8 },
268
+ schema: "barchart",
269
+ builtin: true,
270
+ });
271
+
272
+ export const BarGaugePanel = makePanelClass<"bargauge", bargauge.Options, Record<string, unknown>>({
273
+ type: "bargauge",
274
+ className: "BarGaugePanel",
275
+ description: "Bar gauge: one bar per series, filled against min, max and thresholds",
276
+ defaultSize: { w: 12, h: 8 },
277
+ schema: "bargauge",
278
+ builtin: true,
279
+ });
280
+
281
+ export const PieChartPanel = makePanelClass<"piechart", piechart.Options, piechart.FieldConfig>({
282
+ type: "piechart",
283
+ className: "PieChartPanel",
284
+ description: "Pie chart: each series' share of the total, as a pie or donut",
285
+ defaultSize: { w: 8, h: 8 },
286
+ schema: "piechart",
287
+ builtin: true,
288
+ });
289
+
290
+ export const StateTimelinePanel = makePanelClass<"state-timeline", statetimeline.Options, statetimeline.FieldConfig>({
291
+ type: "state-timeline",
292
+ className: "StateTimelinePanel",
293
+ description: "State timeline: state changes over time, one lane per series",
294
+ defaultSize: { w: 24, h: 8 },
295
+ schema: "statetimeline",
296
+ builtin: true,
297
+ });
298
+
299
+ export const StatusHistoryPanel = makePanelClass<"status-history", statushistory.Options, statushistory.FieldConfig>({
300
+ type: "status-history",
301
+ className: "StatusHistoryPanel",
302
+ description: "Status history: periodic states over time as a grid of cells",
303
+ defaultSize: { w: 24, h: 8 },
304
+ schema: "statushistory",
305
+ builtin: true,
306
+ });
307
+
308
+ export const HistogramPanel = makePanelClass<"histogram", histogram.Options, histogram.FieldConfig>({
309
+ type: "histogram",
310
+ className: "HistogramPanel",
311
+ description: "Histogram: the distribution of values, bucketed, over the whole time range",
312
+ defaultSize: { w: 12, h: 8 },
313
+ schema: "histogram",
314
+ builtin: true,
315
+ });
316
+
317
+ export const NodeGraphPanel = makePanelClass<"nodeGraph", nodegraph.Options, Record<string, unknown>>({
318
+ type: "nodeGraph",
319
+ className: "NodeGraphPanel",
320
+ description: "Node graph: a directed graph of nodes and edges, e.g. a service map",
321
+ defaultSize: { w: 24, h: 12 },
322
+ schema: "nodegraph",
323
+ builtin: true,
324
+ });
325
+
326
+ export const XYChartPanel = makePanelClass<"xychart", xychart.Options, xychart.FieldConfig>({
327
+ type: "xychart",
328
+ className: "XYChartPanel",
329
+ description: "XY chart: one field plotted against another, as points or lines",
330
+ defaultSize: { w: 12, h: 8 },
331
+ schema: "xychart",
332
+ builtin: true,
333
+ });
334
+
335
+ export const TrendPanel = makePanelClass<"trend", trend.Options, trend.FieldConfig>({
336
+ type: "trend",
337
+ className: "TrendPanel",
338
+ description: "Trend: values against a numeric x field that is not time",
339
+ defaultSize: { w: 12, h: 8 },
340
+ schema: "trend",
341
+ builtin: true,
342
+ });
343
+
344
+ export const CanvasPanel = makePanelClass<"canvas", canvas.Options, Record<string, unknown>>({
345
+ type: "canvas",
346
+ className: "CanvasPanel",
347
+ description: "Canvas: freely placed elements, text, icons and metrics bound to data",
348
+ defaultSize: { w: 12, h: 10 },
349
+ schema: "canvas",
350
+ builtin: true,
351
+ });
352
+
353
+ export const GeomapPanel = makePanelClass<"geomap", geomap.Options, Record<string, unknown>>({
354
+ type: "geomap",
355
+ className: "GeomapPanel",
356
+ description: "Geomap: data on a world map, as markers, heatmaps or routes",
357
+ defaultSize: { w: 12, h: 10 },
358
+ schema: "geomap",
359
+ builtin: true,
360
+ });
361
+
362
+ export const FlameGraphPanel = makePanelClass<"flamegraph", FlameGraphOptions, Record<string, unknown>>({
363
+ type: "flamegraph",
364
+ className: "FlameGraphPanel",
365
+ description: "Flame graph: profiling data, e.g. from Pyroscope, as a flame graph and table",
366
+ defaultSize: { w: 24, h: 12 },
367
+ builtin: true,
368
+ });
369
+
370
+ export const AlertListPanel = makePanelClass<"alertlist", AlertListOptions, Record<string, unknown>>({
371
+ type: "alertlist",
372
+ className: "AlertListPanel",
373
+ description: "Alert list: alert rules and their current state, no queries",
374
+ defaultSize: { w: 8, h: 10 },
375
+ builtin: true,
376
+ });
377
+
246
378
  // ── Rows ────────────────────────────────────────────────────────
247
379
 
248
380
  export interface RowProps {
@@ -256,6 +388,12 @@ export interface RowProps {
256
388
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
257
389
  datasource?: DatasourceInput<any>;
258
390
  id?: number;
391
+ /**
392
+ * The grid line the row header sits on. Without it, the row goes on the
393
+ * first free line below everything declared before it. A row header is
394
+ * always full width and one line high, so `y` is all it takes.
395
+ */
396
+ gridPos?: { y: number };
259
397
  }
260
398
 
261
399
  export interface RowEntity extends Declarable {
package/src/pin.ts CHANGED
@@ -5,12 +5,19 @@
5
5
  * kinds. `grafana/grafana-foundation-sdk` runs them through cog and
6
6
  * publishes, beside its builder libraries, one JSON Schema per kind under
7
7
  * `jsonschema/`. This lexicon vendors the files it uses into `src/spec/schemas/`
8
- * (exact bytes, at the commit below) and generates `src/schema/*.gen.ts`
9
- * from them. Nothing is fetched at build or test time.
8
+ * (exact bytes, at the commit below), applies the correction overlay in
9
+ * `src/spec/overlay/` (see `src/spec/overlay.ts`), and generates
10
+ * `src/schema/*.gen.ts` from the result. Nothing is fetched at build or test
11
+ * time.
12
+ *
13
+ * The types track Grafana 12.4 and 13.x: v0.0.20 is labelled with the
14
+ * v11.6.x kind registry, but its dashboard schema largely matches those
15
+ * releases, and the overlay covers the rest.
10
16
  *
11
17
  * Bumping the pin: change `ref` and `commit`, run `just fetch-schemas`
12
18
  * (downloads and prints the new digests), paste the digests here, run
13
- * `npm run generate`, and review the diff of `src/schema/`.
19
+ * `npm run generate` (it refuses overlay patches the new schemas already
20
+ * carry; delete those), and review the diff of `src/schema/`.
14
21
  */
15
22
 
16
23
  export interface GrafanaSchemaPin {
@@ -20,10 +27,13 @@ export interface GrafanaSchemaPin {
20
27
  ref: string;
21
28
  /** The exact commit the vendored files were taken from. */
22
29
  commit: string;
23
- /** The Grafana kind registry version cog generated the schemas from. */
30
+ /**
31
+ * The kind registry label the SDK publishes the schemas under. It lags the
32
+ * content: the v0.0.20 schemas are labelled v11.6.x and cover 12.4 and 13.x.
33
+ */
24
34
  kindRegistry: string;
25
35
  /** sha256 of each vendored file, keyed by schema name (`src/spec/schemas/<name>.jsonschema.json`). */
26
- files: Readonly<Record<SchemaName, string>>;
36
+ files: Readonly<Record<VendoredSchemaName, string>>;
27
37
  }
28
38
 
29
39
  export const SCHEMA_NAMES = [
@@ -35,13 +45,47 @@ export const SCHEMA_NAMES = [
35
45
  "logs",
36
46
  "heatmap",
37
47
  "text",
48
+ "barchart",
49
+ "bargauge",
50
+ "piechart",
51
+ "statetimeline",
52
+ "statushistory",
53
+ "histogram",
54
+ "nodegraph",
55
+ "xychart",
56
+ "trend",
57
+ "canvas",
58
+ "geomap",
38
59
  "prometheus",
39
60
  "tempo",
40
61
  "loki",
62
+ "elasticsearch",
63
+ "cloudwatch",
64
+ "azuremonitor",
65
+ "googlecloudmonitoring",
66
+ "bigquery",
67
+ "grafanapyroscope",
68
+ "expr",
41
69
  ] as const;
42
70
 
43
71
  export type SchemaName = (typeof SCHEMA_NAMES)[number];
44
72
 
73
+ /**
74
+ * Schemas vendored from the same commit for reading, not for types: no
75
+ * `.gen.ts` is generated from them and GRAF107 does not use them, since chant
76
+ * builds classic dashboards. `dashboardv2` is the v2 dashboard kind the
77
+ * importer reads (#2947); `src/import/v2.test.ts` checks the importer knows
78
+ * every key it defines.
79
+ */
80
+ export const IMPORT_ONLY_SCHEMA_NAMES = ["dashboardv2"] as const;
81
+
82
+ export type ImportOnlySchemaName = (typeof IMPORT_ONLY_SCHEMA_NAMES)[number];
83
+
84
+ /** Every schema file under `src/spec/schemas/`. */
85
+ export type VendoredSchemaName = SchemaName | ImportOnlySchemaName;
86
+
87
+ export const VENDORED_SCHEMA_NAMES: readonly VendoredSchemaName[] = [...SCHEMA_NAMES, ...IMPORT_ONLY_SCHEMA_NAMES];
88
+
45
89
  export const GRAFANA_SCHEMA_PIN: GrafanaSchemaPin = Object.freeze({
46
90
  source: "github.com/grafana/grafana-foundation-sdk/jsonschema",
47
91
  ref: "v0.0.20",
@@ -56,13 +100,32 @@ export const GRAFANA_SCHEMA_PIN: GrafanaSchemaPin = Object.freeze({
56
100
  logs: "0254600ef9720bd2c906628304a7c362c0182b4bff2fd7d91352d95a269b2dda",
57
101
  heatmap: "1e1905eef14ada48c121374ecad41412380b317e8183771d99a7504753d5005c",
58
102
  text: "db6d2e3e2c576d1c78ac2e08930f60dbc22bb7ee21abd0cd9204be49f0dbce09",
103
+ barchart: "36f16c10ac3529f88435b81af1d2e352bc915d228a0fb0418d4e46cc2615f6cb",
104
+ bargauge: "dbd22a7b71c4133b880ad39daeaf33c5bf0509fe0d5dc7a882fe3449207b636f",
105
+ piechart: "3edcd85eb8333db755562fc360e392795617582c8d03d11f5918247a4b0ceea9",
106
+ statetimeline: "4df9f488db587b074de51e2b10d6361e3dd390f110aee105029f334b863bd365",
107
+ statushistory: "3149edd7e3c9567913bb123ee764b118c816b9865ab7ec1f19275335b670f4b3",
108
+ histogram: "ef30d7b439b5ece72783be27575b736745aa3eedade37919fcf7560427eb09ac",
109
+ nodegraph: "76595130348310202d87c0efd1e248d60f391cf4cf39c0d3c8d30a251c1f9461",
110
+ xychart: "071b4866d0d292c772adb5946a6cae94cc2486b4a0acabb6247090b5f7a83f9f",
111
+ trend: "599a241e922217be840a65fbf731f7883a3304fd2b6074af01650d325ec0e629",
112
+ canvas: "53e5069cfeef461913cec759c120bc31167b7532be2b69d3c45ce7e4877290d7",
113
+ geomap: "8c8716e9bdbb6b0465b2e91ad1a1100d96a02b7f1be606bd90a6676d94897179",
59
114
  prometheus: "726fc97eeb1e37791dbbf988c3cf40de17bb8e623926e6979c4a3f947cb1af87",
60
115
  tempo: "21aec4c333c9b8e5e9228e85a6225c76161975abb54002e6f12e919e3b4e54ae",
61
116
  loki: "03b81d6b952e3d31785c4b52637e2b7b1c170cc2ea8ec7ec671c21599508e31b",
117
+ elasticsearch: "126b0e04116877f468df7474ad6f75167cf9c54feb125534211fbe1915e6421e",
118
+ cloudwatch: "06d50341c82420865f3f58bfd3e3081cd90fb625f1d275bb7ba0230033f9db3f",
119
+ azuremonitor: "fe0f2fc01ff626dec7ce17a0e3dbb2e76f51f20539c73bbded46bbc4c2d3e262",
120
+ googlecloudmonitoring: "e1f2e2086d4216f22aca84def440b6a31a76e074727aa2ea3d2d10671e68834b",
121
+ bigquery: "939a0a6aee2c98fd8f690659e17060ff2b5bad1b22437e3449741ce0acc5abe4",
122
+ grafanapyroscope: "297db04efc4f9501ffa729acd9e02e484998bc4d823c7da362e401faceed64a2",
123
+ expr: "b1f1c1e4f6bf00f0fb4cb32b5bcc1b0e91fad9b7ad9354ecb791322bd97a5564",
124
+ dashboardv2: "a2cfb8b731ff9f48c41f5aa06ade134cf0d93ab9f6f0567a34a4bc39a9fd984e",
62
125
  }),
63
126
  });
64
127
 
65
128
  /** The raw URL of one schema file at the pinned commit. */
66
- export function schemaUrl(name: SchemaName, pin: GrafanaSchemaPin = GRAFANA_SCHEMA_PIN): string {
129
+ export function schemaUrl(name: VendoredSchemaName, pin: GrafanaSchemaPin = GRAFANA_SCHEMA_PIN): string {
67
130
  return `https://raw.githubusercontent.com/grafana/grafana-foundation-sdk/${pin.commit}/jsonschema/${name}.jsonschema.json`;
68
131
  }
@@ -16,7 +16,7 @@ describe("grafana plugin", () => {
16
16
 
17
17
  it("ships lint rules and post-synth checks, all under the GRAF prefix", () => {
18
18
  const ids = [...grafanaPlugin.lintRules!().map((r) => r.id), ...grafanaPlugin.postSynthChecks!().map((c) => c.id)];
19
- expect(ids).toEqual(["GRAF001", "GRAF002", "GRAF101", "GRAF102", "GRAF103", "GRAF104", "GRAF105", "GRAF106", "GRAF107"]);
19
+ expect(ids).toEqual(["GRAF001", "GRAF002", "GRAF101", "GRAF102", "GRAF103", "GRAF104", "GRAF105", "GRAF106", "GRAF107", "GRAF108", "GRAF109", "GRAF110", "GRAF111", "GRAF112", "GRAF113", "GRAF114", "GRAF115"]);
20
20
  });
21
21
 
22
22
  it("catalogues every rule and check for chant audit, and nothing else", () => {
@@ -29,16 +29,26 @@ describe("grafana plugin", () => {
29
29
  expect(grafanaPlugin.detectTemplate!({ panels: [], schemaVersion: 41, title: "x" })).toBe(true);
30
30
  expect(grafanaPlugin.detectTemplate!({ apiVersion: 1, datasources: [] })).toBe(true);
31
31
  expect(grafanaPlugin.detectTemplate!({ apiVersion: 1, providers: [] })).toBe(true);
32
+ expect(grafanaPlugin.detectTemplate!({ apiVersion: 1, groups: [{ name: "g", folder: "F", rules: [] }] })).toBe(true);
33
+ expect(grafanaPlugin.detectTemplate!({ apiVersion: 1, contactPoints: [] })).toBe(true);
34
+ expect(grafanaPlugin.detectTemplate!({ groups: [{ name: "g", rules: [{ alert: "A", expr: "up == 0" }] }] })).toBe(false);
32
35
  expect(grafanaPlugin.detectTemplate!({ apiVersion: "v1", kind: "ConfigMap" })).toBe(false);
33
36
  expect(grafanaPlugin.detectTemplate!({ receivers: {}, service: { pipelines: {} } })).toBe(false);
34
37
  });
35
38
 
36
39
  it("loads its skills with content", () => {
37
40
  const skills = grafanaPlugin.skills!();
38
- expect(skills.map((s) => s.name)).toEqual(["chant-grafana", "chant-grafana-provisioning"]);
41
+ expect(skills.map((s) => s.name)).toEqual(["chant-grafana", "chant-grafana-provisioning", "chant-grafana-alerting", "chant-grafana-operations"]);
39
42
  for (const s of skills) expect(s.content.length).toBeGreaterThan(200);
40
43
  });
41
44
 
45
+ it("offers a default init template and three named ones", () => {
46
+ const names = [undefined, "red", "k8s-pods", "slo"];
47
+ const sets = names.map((n) => grafanaPlugin.initTemplates!(n));
48
+ expect(new Set(sets).size).toBe(4);
49
+ for (const set of sets) expect(Object.keys(set.src).length).toBeGreaterThan(0);
50
+ });
51
+
42
52
  it("registers namespaced MCP contributions", async () => {
43
53
  expect(grafanaPlugin.mcpTools!().map((t) => t.name)).toEqual(["grafana:diff"]);
44
54
  const [resource] = grafanaPlugin.mcpResources!();
package/src/plugin.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { LexiconPlugin } from "@intentius/chant/lexicon";
2
+ import type { OwnershipChannel } from "@intentius/chant/ownership";
2
3
  import type { CompletionContext, HoverContext } from "@intentius/chant/lsp/types";
3
4
  import type { McpResourceContribution } from "@intentius/chant/mcp/types";
4
5
  import { createDiffTool } from "@intentius/chant/lexicon-plugin-helpers";
@@ -9,10 +10,17 @@ import { grafanaAuditCatalog } from "./lint/audit-catalog";
9
10
  import { completions } from "./lsp/completions";
10
11
  import { hover } from "./lsp/hover";
11
12
  import { detectTemplate } from "./detect";
13
+ import { GrafanaParser } from "./import/parser";
14
+ import { GrafanaGenerator } from "./import/generator";
15
+ import { dashboardImporter } from "./import/embedded";
12
16
  import { grafanaSkills } from "./skill-defs";
17
+ import { DEFAULT_TEMPLATE, K8S_PODS_TEMPLATE, RED_TEMPLATE, SLO_TEMPLATE } from "./init-templates";
13
18
  import { BUILTIN_CATALOG } from "./catalog";
14
19
  import { GRAFANA_SCHEMA_PIN } from "./pin";
15
20
  import { compositeCatalog } from "./composites/catalog";
21
+ import { grafanaConfigSchema } from "./config";
22
+ import { grafanaDeepNormalizationHooks } from "./deep-observe-hooks";
23
+ import { GRAFANA_OWNERSHIP_KEYS } from "./ownership";
16
24
 
17
25
  const catalogResource: McpResourceContribution = {
18
26
  uri: "grafana:resource-catalog",
@@ -24,6 +32,23 @@ const catalogResource: McpResourceContribution = {
24
32
  },
25
33
  };
26
34
 
35
+ /**
36
+ * Where chant's marker can be read (#2946, see ./ownership.ts).
37
+ *
38
+ * A dashboard read over `/apis/dashboard.grafana.app` resolves `owned` or
39
+ * `foreign` on all three paths: from chant's managed-by label (stack and env
40
+ * included) when it was written through the API, or from the manager
41
+ * annotation Grafana writes on a dashboard one of the project's providers
42
+ * loaded. What resolves nothing, and says `unknown`, is kind- and
43
+ * server-shaped rather than path-shaped: datasources (their API has no
44
+ * labels) and dashboards on Grafana 11 (read over `/api/dashboards/uid`).
45
+ * An `owned: true` read withholds those as `filtered`.
46
+ */
47
+ const ownershipChannel: OwnershipChannel = {
48
+ keys: GRAFANA_OWNERSHIP_KEYS,
49
+ reads: ["describeResources", "observeResourcesDeep", "exportResources"],
50
+ };
51
+
27
52
  /**
28
53
  * Grafana lexicon plugin.
29
54
  *
@@ -36,6 +61,8 @@ const catalogResource: McpResourceContribution = {
36
61
  export const grafanaPlugin: LexiconPlugin = {
37
62
  name: "grafana",
38
63
  serializer: grafanaSerializer,
64
+ configSchema: grafanaConfigSchema,
65
+ ownershipChannel,
39
66
 
40
67
  // ── Required lifecycle methods ────────────────────────────────
41
68
 
@@ -75,6 +102,12 @@ export const grafanaPlugin: LexiconPlugin = {
75
102
  return rules;
76
103
  },
77
104
 
105
+ // Panels, rows, queries and variables live inside a dashboard, so core
106
+ // lint does not count them as resources (chant #2957).
107
+ propertyClassNames() {
108
+ return BUILTIN_CATALOG.filter((e) => e.entityKind === "property").map((e) => e.className);
109
+ },
110
+
78
111
  postSynthChecks() {
79
112
  return postSynthChecks;
80
113
  },
@@ -97,10 +130,30 @@ export const grafanaPlugin: LexiconPlugin = {
97
130
  return [catalogResource];
98
131
  },
99
132
 
133
+ // `chant init --lexicon grafana [--template red|k8s-pods|slo]`; see ./init-templates.ts.
134
+ initTemplates(template?: string) {
135
+ if (template === "red") return RED_TEMPLATE;
136
+ if (template === "k8s-pods") return K8S_PODS_TEMPLATE;
137
+ if (template === "slo") return SLO_TEMPLATE;
138
+ return DEFAULT_TEMPLATE;
139
+ },
140
+
100
141
  detectTemplate(data: unknown) {
101
142
  return detectTemplate(data);
102
143
  },
103
144
 
145
+ templateParser() {
146
+ return new GrafanaParser();
147
+ },
148
+
149
+ templateGenerator() {
150
+ return new GrafanaGenerator();
151
+ },
152
+
153
+ embeddedImporters() {
154
+ return [dashboardImporter];
155
+ },
156
+
104
157
  completionProvider(ctx: CompletionContext) {
105
158
  return completions(ctx);
106
159
  },
@@ -109,6 +162,28 @@ export const grafanaPlugin: LexiconPlugin = {
109
162
  return hover(ctx);
110
163
  },
111
164
 
165
+ // ── Live observation and export (#2946) ──────────────────────
166
+ // Behind dynamic imports, so `chant build` never loads a transport. The
167
+ // hooks are static: core normalizes the declared tree with them whether or
168
+ // not a live read happens.
169
+
170
+ async describeResources(options) {
171
+ const { describeResources } = await import("./describe-resources");
172
+ return describeResources(options);
173
+ },
174
+
175
+ async observeResourcesDeep(options) {
176
+ const { observeResourcesDeepGrafana } = await import("./deep-observe");
177
+ return observeResourcesDeepGrafana(options);
178
+ },
179
+
180
+ deepNormalizationHooks: grafanaDeepNormalizationHooks,
181
+
182
+ async exportResources(options) {
183
+ const { exportResources } = await import("./export-resources");
184
+ return exportResources(options);
185
+ },
186
+
112
187
  async docs(options?: { verbose?: boolean }) {
113
188
  const { generateDocs } = await import("./codegen/docs");
114
189
  return generateDocs(options);