@principal-ai/subsystems-core 0.29.0 → 0.31.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 (558) hide show
  1. package/README.md +15 -110
  2. package/dist/index.d.ts +7 -75
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +21 -205
  5. package/dist/index.js.map +1 -1
  6. package/dist/node.d.ts +5 -61
  7. package/dist/node.d.ts.map +1 -1
  8. package/dist/node.js +9 -131
  9. package/dist/node.js.map +1 -1
  10. package/dist/types/index.d.ts +3 -348
  11. package/dist/types/index.d.ts.map +1 -1
  12. package/dist/types/index.js +3 -19
  13. package/dist/types/index.js.map +1 -1
  14. package/dist/types/subsystem-model.d.ts +34 -3
  15. package/dist/types/subsystem-model.d.ts.map +1 -1
  16. package/dist/types/subsystem-model.js.map +1 -1
  17. package/package.json +7 -24
  18. package/schemas/subsystem-model.schema.json +52 -1
  19. package/src/index.ts +7 -580
  20. package/src/node.ts +21 -262
  21. package/src/types/index.ts +3 -456
  22. package/src/types/subsystem-model.ts +39 -3
  23. package/dist/ConfigurationLoader.d.ts +0 -76
  24. package/dist/ConfigurationLoader.d.ts.map +0 -1
  25. package/dist/ConfigurationLoader.js +0 -148
  26. package/dist/ConfigurationLoader.js.map +0 -1
  27. package/dist/ConfigurationValidator.d.ts +0 -31
  28. package/dist/ConfigurationValidator.d.ts.map +0 -1
  29. package/dist/ConfigurationValidator.js +0 -239
  30. package/dist/ConfigurationValidator.js.map +0 -1
  31. package/dist/EventProcessor.d.ts +0 -49
  32. package/dist/EventProcessor.d.ts.map +0 -1
  33. package/dist/EventProcessor.js +0 -220
  34. package/dist/EventProcessor.js.map +0 -1
  35. package/dist/EventRecorderService.d.ts +0 -305
  36. package/dist/EventRecorderService.d.ts.map +0 -1
  37. package/dist/EventRecorderService.js +0 -467
  38. package/dist/EventRecorderService.js.map +0 -1
  39. package/dist/LibraryLoader.d.ts +0 -65
  40. package/dist/LibraryLoader.d.ts.map +0 -1
  41. package/dist/LibraryLoader.js +0 -197
  42. package/dist/LibraryLoader.js.map +0 -1
  43. package/dist/PathBasedEventProcessor.d.ts +0 -77
  44. package/dist/PathBasedEventProcessor.d.ts.map +0 -1
  45. package/dist/PathBasedEventProcessor.js +0 -136
  46. package/dist/PathBasedEventProcessor.js.map +0 -1
  47. package/dist/SessionManager.d.ts +0 -194
  48. package/dist/SessionManager.d.ts.map +0 -1
  49. package/dist/SessionManager.js +0 -302
  50. package/dist/SessionManager.js.map +0 -1
  51. package/dist/ValidationEngine.d.ts +0 -31
  52. package/dist/ValidationEngine.d.ts.map +0 -1
  53. package/dist/ValidationEngine.js +0 -162
  54. package/dist/ValidationEngine.js.map +0 -1
  55. package/dist/auxiliary/AuxiliaryManifestValidator.d.ts +0 -41
  56. package/dist/auxiliary/AuxiliaryManifestValidator.d.ts.map +0 -1
  57. package/dist/auxiliary/AuxiliaryManifestValidator.js +0 -100
  58. package/dist/auxiliary/AuxiliaryManifestValidator.js.map +0 -1
  59. package/dist/auxiliary/index.d.ts +0 -9
  60. package/dist/auxiliary/index.d.ts.map +0 -1
  61. package/dist/auxiliary/index.js +0 -14
  62. package/dist/auxiliary/index.js.map +0 -1
  63. package/dist/auxiliary/validateAreaScopeDisjoint.d.ts +0 -24
  64. package/dist/auxiliary/validateAreaScopeDisjoint.d.ts.map +0 -1
  65. package/dist/auxiliary/validateAreaScopeDisjoint.js +0 -61
  66. package/dist/auxiliary/validateAreaScopeDisjoint.js.map +0 -1
  67. package/dist/cli/codegen.d.ts +0 -41
  68. package/dist/cli/codegen.d.ts.map +0 -1
  69. package/dist/cli/codegen.js +0 -257
  70. package/dist/cli/codegen.js.map +0 -1
  71. package/dist/codegen/type-generator.d.ts +0 -123
  72. package/dist/codegen/type-generator.d.ts.map +0 -1
  73. package/dist/codegen/type-generator.js +0 -433
  74. package/dist/codegen/type-generator.js.map +0 -1
  75. package/dist/codegen/usage-example.d.ts +0 -103
  76. package/dist/codegen/usage-example.d.ts.map +0 -1
  77. package/dist/codegen/usage-example.js +0 -258
  78. package/dist/codegen/usage-example.js.map +0 -1
  79. package/dist/dashboard/DashboardValidator.d.ts +0 -85
  80. package/dist/dashboard/DashboardValidator.d.ts.map +0 -1
  81. package/dist/dashboard/DashboardValidator.js +0 -775
  82. package/dist/dashboard/DashboardValidator.js.map +0 -1
  83. package/dist/dashboard/index.d.ts +0 -6
  84. package/dist/dashboard/index.d.ts.map +0 -1
  85. package/dist/dashboard/index.js +0 -10
  86. package/dist/dashboard/index.js.map +0 -1
  87. package/dist/discovery/CanvasDiscovery.d.ts +0 -160
  88. package/dist/discovery/CanvasDiscovery.d.ts.map +0 -1
  89. package/dist/discovery/CanvasDiscovery.js +0 -865
  90. package/dist/discovery/CanvasDiscovery.js.map +0 -1
  91. package/dist/discovery/CanvasFileManifest.d.ts +0 -86
  92. package/dist/discovery/CanvasFileManifest.d.ts.map +0 -1
  93. package/dist/discovery/CanvasFileManifest.js +0 -338
  94. package/dist/discovery/CanvasFileManifest.js.map +0 -1
  95. package/dist/discovery/LibraryDiscovery.d.ts +0 -108
  96. package/dist/discovery/LibraryDiscovery.d.ts.map +0 -1
  97. package/dist/discovery/LibraryDiscovery.js +0 -263
  98. package/dist/discovery/LibraryDiscovery.js.map +0 -1
  99. package/dist/discovery/types.d.ts +0 -403
  100. package/dist/discovery/types.d.ts.map +0 -1
  101. package/dist/discovery/types.js +0 -6
  102. package/dist/discovery/types.js.map +0 -1
  103. package/dist/events/EventsCanvasValidator.d.ts +0 -139
  104. package/dist/events/EventsCanvasValidator.d.ts.map +0 -1
  105. package/dist/events/EventsCanvasValidator.js +0 -281
  106. package/dist/events/EventsCanvasValidator.js.map +0 -1
  107. package/dist/events/NamespacePathIndex.d.ts +0 -61
  108. package/dist/events/NamespacePathIndex.d.ts.map +0 -1
  109. package/dist/events/NamespacePathIndex.js +0 -74
  110. package/dist/events/NamespacePathIndex.js.map +0 -1
  111. package/dist/events/OtelEventPathsValidator.d.ts +0 -75
  112. package/dist/events/OtelEventPathsValidator.d.ts.map +0 -1
  113. package/dist/events/OtelEventPathsValidator.js +0 -126
  114. package/dist/events/OtelEventPathsValidator.js.map +0 -1
  115. package/dist/events/ScopeEventsValidator.d.ts +0 -68
  116. package/dist/events/ScopeEventsValidator.d.ts.map +0 -1
  117. package/dist/events/ScopeEventsValidator.js +0 -91
  118. package/dist/events/ScopeEventsValidator.js.map +0 -1
  119. package/dist/events/index.d.ts +0 -9
  120. package/dist/events/index.d.ts.map +0 -1
  121. package/dist/events/index.js +0 -12
  122. package/dist/events/index.js.map +0 -1
  123. package/dist/events/path-helpers.d.ts +0 -33
  124. package/dist/events/path-helpers.d.ts.map +0 -1
  125. package/dist/events/path-helpers.js +0 -59
  126. package/dist/events/path-helpers.js.map +0 -1
  127. package/dist/execution/ExecutionLoader.d.ts +0 -135
  128. package/dist/execution/ExecutionLoader.d.ts.map +0 -1
  129. package/dist/execution/ExecutionLoader.js +0 -266
  130. package/dist/execution/ExecutionLoader.js.map +0 -1
  131. package/dist/execution/ExecutionValidator.d.ts +0 -94
  132. package/dist/execution/ExecutionValidator.d.ts.map +0 -1
  133. package/dist/execution/ExecutionValidator.js +0 -503
  134. package/dist/execution/ExecutionValidator.js.map +0 -1
  135. package/dist/generated/graph-converter-execution.types.d.ts +0 -177
  136. package/dist/generated/graph-converter-execution.types.d.ts.map +0 -1
  137. package/dist/generated/graph-converter-execution.types.js +0 -12
  138. package/dist/generated/graph-converter-execution.types.js.map +0 -1
  139. package/dist/helpers/GraphInstrumentationHelper.d.ts +0 -93
  140. package/dist/helpers/GraphInstrumentationHelper.d.ts.map +0 -1
  141. package/dist/helpers/GraphInstrumentationHelper.js +0 -252
  142. package/dist/helpers/GraphInstrumentationHelper.js.map +0 -1
  143. package/dist/matchers/SpanMatcher.d.ts +0 -107
  144. package/dist/matchers/SpanMatcher.d.ts.map +0 -1
  145. package/dist/matchers/SpanMatcher.js +0 -274
  146. package/dist/matchers/SpanMatcher.js.map +0 -1
  147. package/dist/orchestration/TraceOrchestrator.d.ts +0 -71
  148. package/dist/orchestration/TraceOrchestrator.d.ts.map +0 -1
  149. package/dist/orchestration/TraceOrchestrator.js +0 -416
  150. package/dist/orchestration/TraceOrchestrator.js.map +0 -1
  151. package/dist/parsers/OtlpTraceParser.d.ts +0 -131
  152. package/dist/parsers/OtlpTraceParser.d.ts.map +0 -1
  153. package/dist/parsers/OtlpTraceParser.js +0 -310
  154. package/dist/parsers/OtlpTraceParser.js.map +0 -1
  155. package/dist/registry/CompositeRegistry.d.ts +0 -71
  156. package/dist/registry/CompositeRegistry.d.ts.map +0 -1
  157. package/dist/registry/CompositeRegistry.js +0 -113
  158. package/dist/registry/CompositeRegistry.js.map +0 -1
  159. package/dist/registry/EventRegistry.d.ts +0 -79
  160. package/dist/registry/EventRegistry.d.ts.map +0 -1
  161. package/dist/registry/EventRegistry.js +0 -165
  162. package/dist/registry/EventRegistry.js.map +0 -1
  163. package/dist/registry/LocalRegistry.d.ts +0 -111
  164. package/dist/registry/LocalRegistry.d.ts.map +0 -1
  165. package/dist/registry/LocalRegistry.js +0 -335
  166. package/dist/registry/LocalRegistry.js.map +0 -1
  167. package/dist/registry/RemoteRegistry.d.ts +0 -122
  168. package/dist/registry/RemoteRegistry.d.ts.map +0 -1
  169. package/dist/registry/RemoteRegistry.js +0 -399
  170. package/dist/registry/RemoteRegistry.js.map +0 -1
  171. package/dist/registry/VersionRegistry.d.ts +0 -51
  172. package/dist/registry/VersionRegistry.d.ts.map +0 -1
  173. package/dist/registry/VersionRegistry.js +0 -105
  174. package/dist/registry/VersionRegistry.js.map +0 -1
  175. package/dist/rules/config.d.ts +0 -57
  176. package/dist/rules/config.d.ts.map +0 -1
  177. package/dist/rules/config.js +0 -382
  178. package/dist/rules/config.js.map +0 -1
  179. package/dist/rules/engine.d.ts +0 -70
  180. package/dist/rules/engine.d.ts.map +0 -1
  181. package/dist/rules/engine.js +0 -373
  182. package/dist/rules/engine.js.map +0 -1
  183. package/dist/rules/implementations/connection-type-references.d.ts +0 -7
  184. package/dist/rules/implementations/connection-type-references.d.ts.map +0 -1
  185. package/dist/rules/implementations/connection-type-references.js +0 -107
  186. package/dist/rules/implementations/connection-type-references.js.map +0 -1
  187. package/dist/rules/implementations/dead-end-states.d.ts +0 -17
  188. package/dist/rules/implementations/dead-end-states.d.ts.map +0 -1
  189. package/dist/rules/implementations/dead-end-states.js +0 -75
  190. package/dist/rules/implementations/dead-end-states.js.map +0 -1
  191. package/dist/rules/implementations/index.d.ts +0 -23
  192. package/dist/rules/implementations/index.d.ts.map +0 -1
  193. package/dist/rules/implementations/index.js +0 -73
  194. package/dist/rules/implementations/index.js.map +0 -1
  195. package/dist/rules/implementations/minimum-node-sources.d.ts +0 -24
  196. package/dist/rules/implementations/minimum-node-sources.d.ts.map +0 -1
  197. package/dist/rules/implementations/minimum-node-sources.js +0 -59
  198. package/dist/rules/implementations/minimum-node-sources.js.map +0 -1
  199. package/dist/rules/implementations/no-unknown-fields.d.ts +0 -7
  200. package/dist/rules/implementations/no-unknown-fields.d.ts.map +0 -1
  201. package/dist/rules/implementations/no-unknown-fields.js +0 -216
  202. package/dist/rules/implementations/no-unknown-fields.js.map +0 -1
  203. package/dist/rules/implementations/orphaned-edge-types.d.ts +0 -7
  204. package/dist/rules/implementations/orphaned-edge-types.d.ts.map +0 -1
  205. package/dist/rules/implementations/orphaned-edge-types.js +0 -50
  206. package/dist/rules/implementations/orphaned-edge-types.js.map +0 -1
  207. package/dist/rules/implementations/orphaned-node-types.d.ts +0 -7
  208. package/dist/rules/implementations/orphaned-node-types.d.ts.map +0 -1
  209. package/dist/rules/implementations/orphaned-node-types.js +0 -53
  210. package/dist/rules/implementations/orphaned-node-types.js.map +0 -1
  211. package/dist/rules/implementations/required-metadata.d.ts +0 -7
  212. package/dist/rules/implementations/required-metadata.d.ts.map +0 -1
  213. package/dist/rules/implementations/required-metadata.js +0 -48
  214. package/dist/rules/implementations/required-metadata.js.map +0 -1
  215. package/dist/rules/implementations/state-transition-references.d.ts +0 -7
  216. package/dist/rules/implementations/state-transition-references.d.ts.map +0 -1
  217. package/dist/rules/implementations/state-transition-references.js +0 -138
  218. package/dist/rules/implementations/state-transition-references.js.map +0 -1
  219. package/dist/rules/implementations/unreachable-states.d.ts +0 -7
  220. package/dist/rules/implementations/unreachable-states.d.ts.map +0 -1
  221. package/dist/rules/implementations/unreachable-states.js +0 -83
  222. package/dist/rules/implementations/unreachable-states.js.map +0 -1
  223. package/dist/rules/implementations/valid-action-patterns.d.ts +0 -17
  224. package/dist/rules/implementations/valid-action-patterns.d.ts.map +0 -1
  225. package/dist/rules/implementations/valid-action-patterns.js +0 -112
  226. package/dist/rules/implementations/valid-action-patterns.js.map +0 -1
  227. package/dist/rules/implementations/valid-color-format.d.ts +0 -7
  228. package/dist/rules/implementations/valid-color-format.d.ts.map +0 -1
  229. package/dist/rules/implementations/valid-color-format.js +0 -94
  230. package/dist/rules/implementations/valid-color-format.js.map +0 -1
  231. package/dist/rules/implementations/valid-edge-types.d.ts +0 -7
  232. package/dist/rules/implementations/valid-edge-types.d.ts.map +0 -1
  233. package/dist/rules/implementations/valid-edge-types.js +0 -248
  234. package/dist/rules/implementations/valid-edge-types.js.map +0 -1
  235. package/dist/rules/implementations/valid-node-types.d.ts +0 -7
  236. package/dist/rules/implementations/valid-node-types.d.ts.map +0 -1
  237. package/dist/rules/implementations/valid-node-types.js +0 -187
  238. package/dist/rules/implementations/valid-node-types.js.map +0 -1
  239. package/dist/rules/index.d.ts +0 -28
  240. package/dist/rules/index.d.ts.map +0 -1
  241. package/dist/rules/index.js +0 -70
  242. package/dist/rules/index.js.map +0 -1
  243. package/dist/rules/types.d.ts +0 -309
  244. package/dist/rules/types.d.ts.map +0 -1
  245. package/dist/rules/types.js +0 -40
  246. package/dist/rules/types.js.map +0 -1
  247. package/dist/scopes/ScopePathIndex.d.ts +0 -56
  248. package/dist/scopes/ScopePathIndex.d.ts.map +0 -1
  249. package/dist/scopes/ScopePathIndex.js +0 -67
  250. package/dist/scopes/ScopePathIndex.js.map +0 -1
  251. package/dist/scopes/ScopesCanvasValidator.d.ts +0 -76
  252. package/dist/scopes/ScopesCanvasValidator.d.ts.map +0 -1
  253. package/dist/scopes/ScopesCanvasValidator.js +0 -221
  254. package/dist/scopes/ScopesCanvasValidator.js.map +0 -1
  255. package/dist/scopes/index.d.ts +0 -12
  256. package/dist/scopes/index.d.ts.map +0 -1
  257. package/dist/scopes/index.js +0 -30
  258. package/dist/scopes/index.js.map +0 -1
  259. package/dist/scopes/utils.d.ts +0 -85
  260. package/dist/scopes/utils.d.ts.map +0 -1
  261. package/dist/scopes/utils.js +0 -143
  262. package/dist/scopes/utils.js.map +0 -1
  263. package/dist/scopes/validateScopeNamespaceNesting.d.ts +0 -38
  264. package/dist/scopes/validateScopeNamespaceNesting.d.ts.map +0 -1
  265. package/dist/scopes/validateScopeNamespaceNesting.js +0 -69
  266. package/dist/scopes/validateScopeNamespaceNesting.js.map +0 -1
  267. package/dist/spans/index.d.ts +0 -12
  268. package/dist/spans/index.d.ts.map +0 -1
  269. package/dist/spans/index.js +0 -25
  270. package/dist/spans/index.js.map +0 -1
  271. package/dist/spans/utils.d.ts +0 -70
  272. package/dist/spans/utils.d.ts.map +0 -1
  273. package/dist/spans/utils.js +0 -205
  274. package/dist/spans/utils.js.map +0 -1
  275. package/dist/storyboard/builder.d.ts +0 -135
  276. package/dist/storyboard/builder.d.ts.map +0 -1
  277. package/dist/storyboard/builder.js +0 -235
  278. package/dist/storyboard/builder.js.map +0 -1
  279. package/dist/storyboard/index.d.ts +0 -9
  280. package/dist/storyboard/index.d.ts.map +0 -1
  281. package/dist/storyboard/index.js +0 -18
  282. package/dist/storyboard/index.js.map +0 -1
  283. package/dist/storyboard/types.d.ts +0 -101
  284. package/dist/storyboard/types.d.ts.map +0 -1
  285. package/dist/storyboard/types.js +0 -10
  286. package/dist/storyboard/types.js.map +0 -1
  287. package/dist/telemetry/coverage.d.ts +0 -92
  288. package/dist/telemetry/coverage.d.ts.map +0 -1
  289. package/dist/telemetry/coverage.js +0 -335
  290. package/dist/telemetry/coverage.js.map +0 -1
  291. package/dist/telemetry/event-validator.d.ts +0 -86
  292. package/dist/telemetry/event-validator.d.ts.map +0 -1
  293. package/dist/telemetry/event-validator.js +0 -257
  294. package/dist/telemetry/event-validator.js.map +0 -1
  295. package/dist/types/audit.d.ts +0 -236
  296. package/dist/types/audit.d.ts.map +0 -1
  297. package/dist/types/audit.js +0 -53
  298. package/dist/types/audit.js.map +0 -1
  299. package/dist/types/auxiliary.d.ts +0 -54
  300. package/dist/types/auxiliary.d.ts.map +0 -1
  301. package/dist/types/auxiliary.js +0 -27
  302. package/dist/types/auxiliary.js.map +0 -1
  303. package/dist/types/canvas-scope.d.ts +0 -156
  304. package/dist/types/canvas-scope.d.ts.map +0 -1
  305. package/dist/types/canvas-scope.js +0 -62
  306. package/dist/types/canvas-scope.js.map +0 -1
  307. package/dist/types/canvas.d.ts +0 -1138
  308. package/dist/types/canvas.d.ts.map +0 -1
  309. package/dist/types/canvas.js +0 -178
  310. package/dist/types/canvas.js.map +0 -1
  311. package/dist/types/dashboard.d.ts +0 -170
  312. package/dist/types/dashboard.d.ts.map +0 -1
  313. package/dist/types/dashboard.js +0 -14
  314. package/dist/types/dashboard.js.map +0 -1
  315. package/dist/types/library.d.ts +0 -227
  316. package/dist/types/library.d.ts.map +0 -1
  317. package/dist/types/library.js +0 -16
  318. package/dist/types/library.js.map +0 -1
  319. package/dist/types/otel.d.ts +0 -465
  320. package/dist/types/otel.d.ts.map +0 -1
  321. package/dist/types/otel.js +0 -163
  322. package/dist/types/otel.js.map +0 -1
  323. package/dist/types/path-based-config.d.ts +0 -235
  324. package/dist/types/path-based-config.d.ts.map +0 -1
  325. package/dist/types/path-based-config.js +0 -11
  326. package/dist/types/path-based-config.js.map +0 -1
  327. package/dist/types/registered-trace.d.ts +0 -337
  328. package/dist/types/registered-trace.d.ts.map +0 -1
  329. package/dist/types/registered-trace.js +0 -16
  330. package/dist/types/registered-trace.js.map +0 -1
  331. package/dist/types/resource-match.d.ts +0 -207
  332. package/dist/types/resource-match.d.ts.map +0 -1
  333. package/dist/types/resource-match.js +0 -74
  334. package/dist/types/resource-match.js.map +0 -1
  335. package/dist/types/version-registry.d.ts +0 -137
  336. package/dist/types/version-registry.d.ts.map +0 -1
  337. package/dist/types/version-registry.js +0 -10
  338. package/dist/types/version-registry.js.map +0 -1
  339. package/dist/utils/CanvasConverter.d.ts +0 -148
  340. package/dist/utils/CanvasConverter.d.ts.map +0 -1
  341. package/dist/utils/CanvasConverter.js +0 -530
  342. package/dist/utils/CanvasConverter.js.map +0 -1
  343. package/dist/utils/GraphConverter.d.ts +0 -18
  344. package/dist/utils/GraphConverter.d.ts.map +0 -1
  345. package/dist/utils/GraphConverter.js +0 -80
  346. package/dist/utils/GraphConverter.js.map +0 -1
  347. package/dist/utils/PathMatcher.d.ts +0 -55
  348. package/dist/utils/PathMatcher.d.ts.map +0 -1
  349. package/dist/utils/PathMatcher.js +0 -178
  350. package/dist/utils/PathMatcher.js.map +0 -1
  351. package/dist/utils/TraceToCanvas.d.ts +0 -83
  352. package/dist/utils/TraceToCanvas.d.ts.map +0 -1
  353. package/dist/utils/TraceToCanvas.js +0 -336
  354. package/dist/utils/TraceToCanvas.js.map +0 -1
  355. package/dist/utils/YamlParser.d.ts +0 -36
  356. package/dist/utils/YamlParser.d.ts.map +0 -1
  357. package/dist/utils/YamlParser.js +0 -92
  358. package/dist/utils/YamlParser.js.map +0 -1
  359. package/dist/utils/registeredTraceHelpers.d.ts +0 -76
  360. package/dist/utils/registeredTraceHelpers.d.ts.map +0 -1
  361. package/dist/utils/registeredTraceHelpers.js +0 -203
  362. package/dist/utils/registeredTraceHelpers.js.map +0 -1
  363. package/dist/utils/traceAggregation.d.ts +0 -25
  364. package/dist/utils/traceAggregation.d.ts.map +0 -1
  365. package/dist/utils/traceAggregation.js +0 -140
  366. package/dist/utils/traceAggregation.js.map +0 -1
  367. package/dist/validation/OtelCanvasValidator.d.ts +0 -40
  368. package/dist/validation/OtelCanvasValidator.d.ts.map +0 -1
  369. package/dist/validation/OtelCanvasValidator.js +0 -59
  370. package/dist/validation/OtelCanvasValidator.js.map +0 -1
  371. package/dist/validation/index.d.ts +0 -8
  372. package/dist/validation/index.d.ts.map +0 -1
  373. package/dist/validation/index.js +0 -13
  374. package/dist/validation/index.js.map +0 -1
  375. package/dist/validation/libraryValidation.d.ts +0 -53
  376. package/dist/validation/libraryValidation.d.ts.map +0 -1
  377. package/dist/validation/libraryValidation.js +0 -115
  378. package/dist/validation/libraryValidation.js.map +0 -1
  379. package/dist/workflow/edge-derivation.d.ts +0 -111
  380. package/dist/workflow/edge-derivation.d.ts.map +0 -1
  381. package/dist/workflow/edge-derivation.js +0 -174
  382. package/dist/workflow/edge-derivation.js.map +0 -1
  383. package/dist/workflow/edge-validation.d.ts +0 -170
  384. package/dist/workflow/edge-validation.d.ts.map +0 -1
  385. package/dist/workflow/edge-validation.js +0 -332
  386. package/dist/workflow/edge-validation.js.map +0 -1
  387. package/dist/workflow/example.d.ts +0 -11
  388. package/dist/workflow/example.d.ts.map +0 -1
  389. package/dist/workflow/example.js +0 -310
  390. package/dist/workflow/example.js.map +0 -1
  391. package/dist/workflow/index.d.ts +0 -20
  392. package/dist/workflow/index.d.ts.map +0 -1
  393. package/dist/workflow/index.js +0 -49
  394. package/dist/workflow/index.js.map +0 -1
  395. package/dist/workflow/scenario-matcher.d.ts +0 -63
  396. package/dist/workflow/scenario-matcher.d.ts.map +0 -1
  397. package/dist/workflow/scenario-matcher.js +0 -215
  398. package/dist/workflow/scenario-matcher.js.map +0 -1
  399. package/dist/workflow/template-parser.d.ts +0 -73
  400. package/dist/workflow/template-parser.d.ts.map +0 -1
  401. package/dist/workflow/template-parser.js +0 -280
  402. package/dist/workflow/template-parser.js.map +0 -1
  403. package/dist/workflow/template-renderer.d.ts +0 -45
  404. package/dist/workflow/template-renderer.d.ts.map +0 -1
  405. package/dist/workflow/template-renderer.js +0 -401
  406. package/dist/workflow/template-renderer.js.map +0 -1
  407. package/dist/workflow/types.d.ts +0 -393
  408. package/dist/workflow/types.d.ts.map +0 -1
  409. package/dist/workflow/types.js +0 -40
  410. package/dist/workflow/types.js.map +0 -1
  411. package/dist/workflow/validator.d.ts +0 -363
  412. package/dist/workflow/validator.d.ts.map +0 -1
  413. package/dist/workflow/validator.js +0 -2283
  414. package/dist/workflow/validator.js.map +0 -1
  415. package/schemas/auxiliary.manifest.schema.json +0 -56
  416. package/src/ConfigurationLoader.test.ts +0 -466
  417. package/src/ConfigurationLoader.ts +0 -184
  418. package/src/ConfigurationValidator.test.ts +0 -200
  419. package/src/ConfigurationValidator.ts +0 -273
  420. package/src/EventProcessor.test.ts +0 -405
  421. package/src/EventProcessor.ts +0 -256
  422. package/src/EventRecorderService.test.ts +0 -543
  423. package/src/EventRecorderService.ts +0 -741
  424. package/src/LibraryLoader.ts +0 -194
  425. package/src/PathBasedEventProcessor.test.ts +0 -336
  426. package/src/PathBasedEventProcessor.ts +0 -196
  427. package/src/SessionManager.test.ts +0 -424
  428. package/src/SessionManager.ts +0 -471
  429. package/src/ValidationEngine.test.ts +0 -520
  430. package/src/ValidationEngine.ts +0 -200
  431. package/src/auxiliary/AuxiliaryManifestValidator.test.ts +0 -93
  432. package/src/auxiliary/AuxiliaryManifestValidator.ts +0 -132
  433. package/src/auxiliary/index.ts +0 -18
  434. package/src/auxiliary/validateAreaScopeDisjoint.test.ts +0 -85
  435. package/src/auxiliary/validateAreaScopeDisjoint.ts +0 -72
  436. package/src/cli/codegen.ts +0 -286
  437. package/src/codegen/type-generator.test.ts +0 -219
  438. package/src/codegen/type-generator.ts +0 -560
  439. package/src/codegen/usage-example.ts +0 -357
  440. package/src/dashboard/DashboardValidator.ts +0 -904
  441. package/src/dashboard/index.ts +0 -14
  442. package/src/discovery/CanvasDiscovery.test.ts +0 -691
  443. package/src/discovery/CanvasDiscovery.ts +0 -1114
  444. package/src/discovery/CanvasFileManifest.test.ts +0 -521
  445. package/src/discovery/CanvasFileManifest.ts +0 -419
  446. package/src/discovery/LibraryDiscovery.test.ts +0 -329
  447. package/src/discovery/LibraryDiscovery.ts +0 -386
  448. package/src/discovery/types.ts +0 -453
  449. package/src/events/EventsCanvasValidator.test.ts +0 -191
  450. package/src/events/EventsCanvasValidator.ts +0 -428
  451. package/src/events/NamespacePathIndex.test.ts +0 -97
  452. package/src/events/NamespacePathIndex.ts +0 -100
  453. package/src/events/OtelEventPathsValidator.test.ts +0 -243
  454. package/src/events/OtelEventPathsValidator.ts +0 -191
  455. package/src/events/ScopeEventsValidator.test.ts +0 -173
  456. package/src/events/ScopeEventsValidator.ts +0 -158
  457. package/src/events/index.ts +0 -27
  458. package/src/events/path-helpers.ts +0 -53
  459. package/src/execution/ExecutionLoader.test.ts +0 -378
  460. package/src/execution/ExecutionLoader.ts +0 -331
  461. package/src/execution/ExecutionValidator.test.ts +0 -503
  462. package/src/execution/ExecutionValidator.ts +0 -617
  463. package/src/generated/graph-converter-execution.types.ts +0 -193
  464. package/src/helpers/GraphInstrumentationHelper.test.ts +0 -364
  465. package/src/helpers/GraphInstrumentationHelper.ts +0 -323
  466. package/src/matchers/SpanMatcher.test.ts +0 -1105
  467. package/src/matchers/SpanMatcher.ts +0 -381
  468. package/src/orchestration/TraceOrchestrator.ts +0 -560
  469. package/src/orchestration/__tests__/TraceOrchestrator.test.ts +0 -1098
  470. package/src/parsers/OtlpTraceParser.ts +0 -401
  471. package/src/parsers/__tests__/OtlpTraceParser.test.ts +0 -197
  472. package/src/registry/CompositeRegistry.ts +0 -140
  473. package/src/registry/EventRegistry.test.ts +0 -387
  474. package/src/registry/EventRegistry.ts +0 -191
  475. package/src/registry/LocalRegistry.ts +0 -416
  476. package/src/registry/RemoteRegistry.ts +0 -499
  477. package/src/registry/VersionRegistry.test.ts +0 -223
  478. package/src/registry/VersionRegistry.ts +0 -121
  479. package/src/rules/config.test.ts +0 -277
  480. package/src/rules/config.ts +0 -450
  481. package/src/rules/engine.test.ts +0 -331
  482. package/src/rules/engine.ts +0 -448
  483. package/src/rules/implementations/connection-type-references.ts +0 -117
  484. package/src/rules/implementations/dead-end-states.ts +0 -101
  485. package/src/rules/implementations/index.ts +0 -66
  486. package/src/rules/implementations/minimum-node-sources.ts +0 -84
  487. package/src/rules/implementations/no-unknown-fields.ts +0 -372
  488. package/src/rules/implementations/orphaned-edge-types.ts +0 -55
  489. package/src/rules/implementations/orphaned-node-types.ts +0 -58
  490. package/src/rules/implementations/required-metadata.ts +0 -52
  491. package/src/rules/implementations/state-transition-references.ts +0 -155
  492. package/src/rules/implementations/unreachable-states.ts +0 -94
  493. package/src/rules/implementations/valid-action-patterns.ts +0 -140
  494. package/src/rules/implementations/valid-color-format.ts +0 -152
  495. package/src/rules/implementations/valid-edge-types.ts +0 -273
  496. package/src/rules/implementations/valid-node-types.ts +0 -200
  497. package/src/rules/index.ts +0 -92
  498. package/src/rules/types.ts +0 -426
  499. package/src/scopes/ScopePathIndex.test.ts +0 -94
  500. package/src/scopes/ScopePathIndex.ts +0 -89
  501. package/src/scopes/ScopesCanvasValidator.test.ts +0 -127
  502. package/src/scopes/ScopesCanvasValidator.ts +0 -305
  503. package/src/scopes/__tests__/utils.test.ts +0 -383
  504. package/src/scopes/index.ts +0 -42
  505. package/src/scopes/utils.ts +0 -182
  506. package/src/scopes/validateScopeNamespaceNesting.test.ts +0 -127
  507. package/src/scopes/validateScopeNamespaceNesting.ts +0 -88
  508. package/src/spans/index.ts +0 -24
  509. package/src/spans/utils.ts +0 -249
  510. package/src/storyboard/builder.ts +0 -308
  511. package/src/storyboard/index.ts +0 -26
  512. package/src/storyboard/types.ts +0 -117
  513. package/src/telemetry/coverage.ts +0 -480
  514. package/src/telemetry/event-validator.ts +0 -312
  515. package/src/types/audit.ts +0 -314
  516. package/src/types/auxiliary.ts +0 -63
  517. package/src/types/canvas-scope.ts +0 -190
  518. package/src/types/canvas.test.ts +0 -199
  519. package/src/types/canvas.ts +0 -1395
  520. package/src/types/dashboard.ts +0 -257
  521. package/src/types/library.ts +0 -283
  522. package/src/types/otel.test.ts +0 -219
  523. package/src/types/otel.ts +0 -620
  524. package/src/types/path-based-config.ts +0 -285
  525. package/src/types/registered-trace.ts +0 -432
  526. package/src/types/resource-match.ts +0 -263
  527. package/src/types/version-registry.ts +0 -150
  528. package/src/utils/CanvasConverter.ts +0 -670
  529. package/src/utils/GraphConverter.test.ts +0 -322
  530. package/src/utils/GraphConverter.ts +0 -84
  531. package/src/utils/PathMatcher.test.ts +0 -139
  532. package/src/utils/PathMatcher.ts +0 -185
  533. package/src/utils/TraceToCanvas.test.ts +0 -310
  534. package/src/utils/TraceToCanvas.ts +0 -510
  535. package/src/utils/YamlParser.ts +0 -77
  536. package/src/utils/registeredTraceHelpers.ts +0 -251
  537. package/src/utils/traceAggregation.test.ts +0 -385
  538. package/src/utils/traceAggregation.ts +0 -173
  539. package/src/validation/OtelCanvasValidator.ts +0 -86
  540. package/src/validation/index.ts +0 -17
  541. package/src/validation/libraryValidation.ts +0 -206
  542. package/src/workflow/README.md +0 -408
  543. package/src/workflow/__tests__/edge-derivation.test.ts +0 -449
  544. package/src/workflow/__tests__/edge-validation.test.ts +0 -417
  545. package/src/workflow/__tests__/scenario-matcher.test.ts +0 -225
  546. package/src/workflow/__tests__/template-parser.test.ts +0 -276
  547. package/src/workflow/__tests__/template-renderer.test.ts +0 -509
  548. package/src/workflow/__tests__/types.test.ts +0 -187
  549. package/src/workflow/__tests__/validator.test.ts +0 -3225
  550. package/src/workflow/edge-derivation.ts +0 -265
  551. package/src/workflow/edge-validation.ts +0 -503
  552. package/src/workflow/example.ts +0 -330
  553. package/src/workflow/index.ts +0 -86
  554. package/src/workflow/scenario-matcher.ts +0 -253
  555. package/src/workflow/template-parser.ts +0 -350
  556. package/src/workflow/template-renderer.ts +0 -453
  557. package/src/workflow/types.ts +0 -511
  558. package/src/workflow/validator.ts +0 -2737
@@ -1,1114 +0,0 @@
1
- /**
2
- * Unified discovery system for canvas and execution files in a package-aware way
3
- */
4
-
5
- import type { FileTree, GitStatusWithFiles } from '@principal-ai/repository-abstraction';
6
- import { PackageLayerModule, type PackageLayer } from '@principal-ai/codebase-composition';
7
- import type {
8
- DiscoveredCanvas,
9
- DiscoveredCanvasWithContent,
10
- DiscoveredTestTrace,
11
- DiscoveredTestTraceWithContent,
12
- DiscoveredWorkflow,
13
- DiscoveredWorkflowWithContent,
14
- DiscoveredStoryboard,
15
- DiscoveredStoryboardWithContent,
16
- DiscoveredDashboard,
17
- DiscoveredDashboardWithContent,
18
- CanvasDiscoveryResult,
19
- DiscoveryOptions,
20
- CanvasType,
21
- ReferencedSpan,
22
- } from './types';
23
- import { deriveWorkflowEdges } from '../workflow/edge-derivation';
24
- import type { ExtendedCanvas } from '../types/canvas';
25
- import { isOtelSpanConventionNode, isOtelScopeNode } from '../types/canvas';
26
- import { OtelCanvasValidator } from '../validation/OtelCanvasValidator';
27
-
28
- /** Info about a span convention extracted from spans.canvas */
29
- interface SpanInfo {
30
- /** Display label from spans.canvas node label field */
31
- label?: string;
32
- /** Instrumentation scope from spans.canvas node otel.scope field */
33
- scope?: string;
34
- }
35
-
36
- /** Lookup map from span pattern to span info (label, scope) */
37
- type SpanLookup = Map<string, SpanInfo>;
38
-
39
- /** Lookup map from scope name to display label */
40
- type ScopeLabelLookup = Map<string, string>;
41
-
42
- /**
43
- * Unified discovery system for canvas and execution files in a package-aware way
44
- *
45
- * @example
46
- * // Basic usage without content parsing
47
- * const discovery = new CanvasDiscovery();
48
- * const result = await discovery.discover(fileTree);
49
- *
50
- * @example
51
- * // With content parsing (CLI)
52
- * const result = await discovery.discover(fileTree, {
53
- * fileReader: async (path) => fs.promises.readFile(path, 'utf-8'),
54
- * includeContent: true
55
- * });
56
- *
57
- * @example
58
- * // With content parsing (panels)
59
- * const result = await discovery.discover(fileTree, {
60
- * fileReader: async (path) => context.getSlice('fileCache').read(path),
61
- * includeContent: true
62
- * });
63
- */
64
- export class CanvasDiscovery {
65
- private static readonly CANVAS_DIR = '.principal-views';
66
- private static readonly WORKFLOW_EXTENSION = '.workflow.json';
67
- private static readonly DASHBOARD_EXTENSION = '.dashboard.json';
68
-
69
- private packageModule: PackageLayerModule;
70
- private packageCache: Map<string, PackageLayer[]> = new Map();
71
-
72
- constructor() {
73
- this.packageModule = new PackageLayerModule();
74
- }
75
-
76
- /**
77
- * Build a lookup map from span pattern to span info from spans.canvas files
78
- *
79
- * @param canvases - Discovered canvases (must include content for spans.canvas)
80
- * @returns Map of spanPattern → { label?, scope? }
81
- */
82
- private buildSpanLookup(
83
- canvases: (DiscoveredCanvas | DiscoveredCanvasWithContent)[]
84
- ): SpanLookup {
85
- const lookup: SpanLookup = new Map();
86
-
87
- for (const canvas of canvases) {
88
- // Only process spans.canvas files with content
89
- if (canvas.type !== 'spans') continue;
90
-
91
- const canvasWithContent = canvas as DiscoveredCanvasWithContent;
92
- const content = canvasWithContent.content as ExtendedCanvas | undefined;
93
- if (!content?.nodes) continue;
94
-
95
- // Extract span patterns, labels, and scopes from otel-span-convention nodes
96
- for (const node of content.nodes) {
97
- if (isOtelSpanConventionNode(node)) {
98
- const spanPattern = node.otel?.spanPattern;
99
- if (spanPattern) {
100
- lookup.set(spanPattern, {
101
- label: node.label,
102
- scope: node.otel?.scope,
103
- });
104
- }
105
- }
106
- }
107
- }
108
-
109
- return lookup;
110
- }
111
-
112
- /**
113
- * Build a lookup map from scope name to display label from scopes.canvas files
114
- *
115
- * @param canvases - Discovered canvases (must include content for scopes.canvas)
116
- * @returns Map of scopeName → label
117
- */
118
- private buildScopeLabelLookup(
119
- canvases: (DiscoveredCanvas | DiscoveredCanvasWithContent)[]
120
- ): ScopeLabelLookup {
121
- const lookup: ScopeLabelLookup = new Map();
122
-
123
- for (const canvas of canvases) {
124
- // Only process scopes.canvas files with content
125
- if (canvas.type !== 'scopes') continue;
126
-
127
- const canvasWithContent = canvas as DiscoveredCanvasWithContent;
128
- const content = canvasWithContent.content as ExtendedCanvas | undefined;
129
- if (!content?.nodes) continue;
130
-
131
- // Extract scope names and labels from otel-scope nodes
132
- for (const node of content.nodes) {
133
- if (isOtelScopeNode(node)) {
134
- const scopeName = node.otel.scope;
135
- const label = node.label;
136
- if (scopeName && label) {
137
- lookup.set(scopeName, label);
138
- }
139
- }
140
- }
141
- }
142
-
143
- return lookup;
144
- }
145
-
146
- /**
147
- * Discover all canvas, workflow, and test trace files in the file tree
148
- *
149
- * @param fileTree - FileTree from repository-abstraction
150
- * @param options - Discovery options (fileReader, includeContent)
151
- * @returns Discovery result with canvases, testTraces, storyboards, and errors
152
- */
153
- async discover(
154
- fileTree: FileTree,
155
- options: DiscoveryOptions = {}
156
- ): Promise<CanvasDiscoveryResult> {
157
- const errors: Array<{ path: string; error: string }> = [];
158
- const warnings: Array<{ path: string; message: string; type: 'deprecation' }> = [];
159
-
160
- // 1. Discover packages (with caching by fileTree.sha)
161
- const packages = await this.discoverPackagesWithCache(fileTree, options.fileReader);
162
-
163
- // 2. Build package lookup map for efficient path matching
164
- const packageMap = this.buildPackageMap(packages);
165
-
166
- // 3. Discover canvas files
167
- const canvases = await this.discoverCanvasFiles(fileTree, packageMap, options, errors);
168
-
169
- // 3.5. Build span lookup from spans.canvas files (for enriching workflow referencedSpans with labels and scopes)
170
- const spanLookup = this.buildSpanLookup(canvases);
171
-
172
- // 3.6. Build scope label lookup from scopes.canvas files (for resolving scope display names)
173
- const scopeLabelLookup = this.buildScopeLabelLookup(canvases);
174
-
175
- // 4. Discover storyboards (hierarchical organization)
176
- // Note: Test traces are discovered as part of workflows, not separately
177
- const storyboards = await this.discoverStoryboards(fileTree, packageMap, canvases, options, errors, spanLookup, scopeLabelLookup);
178
-
179
- // 5. Collect all test traces from workflows for backward compatibility
180
- const testTraces: (DiscoveredTestTrace | DiscoveredTestTraceWithContent)[] = [];
181
- for (const storyboard of storyboards) {
182
- for (const workflow of storyboard.workflows) {
183
- testTraces.push(...workflow.testTraces);
184
- }
185
- }
186
-
187
- // 6. Discover dashboard files from .principal-views/dashboards/
188
- const dashboards = await this.discoverDashboards(fileTree, packageMap, options, errors);
189
-
190
- // 7. Detect legacy flat canvas structures and add deprecation errors
191
- this.detectLegacyStructures(canvases, storyboards, errors);
192
-
193
- // 8. Validate required canvas types
194
- this.validateRequiredCanvases(canvases, storyboards, errors);
195
-
196
- // 8.5. Validate scope hierarchy (when content is loaded)
197
- if (options.includeContent) {
198
- this.validateScopeHierarchy(storyboards, spanLookup, scopeLabelLookup, errors);
199
- }
200
-
201
- // 9. Sort results
202
- canvases.sort(this.compareByPackageThenName);
203
- testTraces.sort(this.compareByPackageThenName);
204
- storyboards.sort(this.compareByPackageThenName);
205
- dashboards.sort(this.compareByPackageThenName);
206
-
207
- return { canvases, testTraces, storyboards, dashboards, errors, warnings };
208
- }
209
-
210
- /**
211
- * Clear package cache (useful when file tree changes)
212
- */
213
- clearCache(): void {
214
- this.packageCache.clear();
215
- }
216
-
217
- /**
218
- * Check if a file path is relevant to canvas discovery
219
- * Uses package-aware path matching for .principal-views directories
220
- */
221
- isRelevantPath(path: string): boolean {
222
- // Canvas files (.canvas, .otel.canvas)
223
- if (this.isInCanvasDir(path) && this.parseCanvasPath(path)) {
224
- return true;
225
- }
226
- // Workflow files (.workflow.json) in .principal-views
227
- if (path.includes(CanvasDiscovery.CANVAS_DIR) && path.endsWith(CanvasDiscovery.WORKFLOW_EXTENSION)) {
228
- return true;
229
- }
230
- // Dashboard files (.dashboard.json) in .principal-views
231
- if (path.includes(CanvasDiscovery.CANVAS_DIR) && path.endsWith(CanvasDiscovery.DASHBOARD_EXTENSION)) {
232
- return true;
233
- }
234
- // Test trace files (.otel.json) in .principal-views
235
- if (path.includes(CanvasDiscovery.CANVAS_DIR) && path.endsWith('.otel.json')) {
236
- return true;
237
- }
238
- return false;
239
- }
240
-
241
- /**
242
- * Get all file paths in the FileTree that are relevant to canvas discovery
243
- * Uses package-aware path matching (respects packages/\*\/.principal-views/ etc.)
244
- *
245
- * @param fileTree - FileTree from repository-abstraction
246
- * @returns Set of relevant file paths
247
- */
248
- getRelevantPaths(fileTree: FileTree): Set<string> {
249
- const paths = new Set<string>();
250
-
251
- for (const file of fileTree.allFiles) {
252
- const path = file.relativePath || file.path || '';
253
- if (this.isRelevantPath(path)) {
254
- paths.add(path);
255
- }
256
- }
257
-
258
- return paths;
259
- }
260
-
261
- /**
262
- * Filter git status to only include changes relevant to canvas discovery
263
- *
264
- * For existing/modified/deleted files: filters to paths in the current FileTree's relevant paths
265
- * For new/untracked files: checks if they match discovery patterns (could be new canvas files)
266
- *
267
- * @param fileTree - FileTree from repository-abstraction
268
- * @param gitStatus - Git status with file lists
269
- * @returns Filtered git status containing only relevant changes, or null if no relevant changes
270
- */
271
- filterRelevantGitChanges(
272
- fileTree: FileTree,
273
- gitStatus: GitStatusWithFiles
274
- ): GitStatusWithFiles | null {
275
- const relevantPaths = this.getRelevantPaths(fileTree);
276
-
277
- // For existing files: filter to paths we know about
278
- const filterExisting = (paths: string[]) =>
279
- paths.filter(p => relevantPaths.has(p));
280
-
281
- // For new/untracked files: check if they match discovery patterns
282
- const filterNew = (paths: string[]) =>
283
- paths.filter(p => this.isRelevantPath(p));
284
-
285
- const filtered: GitStatusWithFiles = {
286
- ...gitStatus,
287
- modifiedFiles: filterExisting(gitStatus.modifiedFiles),
288
- stagedFiles: filterNew(gitStatus.stagedFiles),
289
- untrackedFiles: filterNew(gitStatus.untrackedFiles),
290
- deletedFiles: filterExisting(gitStatus.deletedFiles),
291
- createdFiles: filterNew(gitStatus.createdFiles || []),
292
- };
293
-
294
- // Return null if no relevant changes
295
- const hasChanges =
296
- filtered.modifiedFiles.length > 0 ||
297
- filtered.stagedFiles.length > 0 ||
298
- filtered.untrackedFiles.length > 0 ||
299
- filtered.deletedFiles.length > 0 ||
300
- filtered.createdFiles.length > 0;
301
-
302
- return hasChanges ? filtered : null;
303
- }
304
-
305
- /**
306
- * Discover storyboards (hierarchical organization of canvas + workflows + executions)
307
- */
308
- private async discoverStoryboards(
309
- fileTree: FileTree,
310
- packageMap: Map<string, PackageLayer>,
311
- canvases: DiscoveredCanvas[],
312
- options: DiscoveryOptions,
313
- errors: Array<{ path: string; error: string }>,
314
- spanLookup: SpanLookup,
315
- scopeLabelLookup: ScopeLabelLookup
316
- ): Promise<(DiscoveredStoryboard | DiscoveredStoryboardWithContent)[]> {
317
- const storyboards: (DiscoveredStoryboard | DiscoveredStoryboardWithContent)[] = [];
318
-
319
- // Build a map of directories to check for storyboards
320
- const storyboardDirs = new Map<string, Set<string>>();
321
-
322
- // Find all directories in .principal-views/ that have subdirectories
323
- for (const file of fileTree.allFiles) {
324
- const path = file.relativePath || file.path || '';
325
- const parts = path.split('/');
326
-
327
- // Look for paths like: .principal-views/storyboard-name/workflow-name/...
328
- // Or: packages/subsystems-core/.principal-views/storyboard-name/workflow-name/...
329
- const pvIndex = parts.indexOf(CanvasDiscovery.CANVAS_DIR);
330
- if (pvIndex === -1 || parts.length < pvIndex + 3) continue;
331
-
332
- const storyboardName = parts[pvIndex + 1];
333
- const storyboardPath = parts.slice(0, pvIndex + 2).join('/');
334
-
335
- if (!storyboardDirs.has(storyboardPath)) {
336
- storyboardDirs.set(storyboardPath, new Set());
337
- }
338
- storyboardDirs.get(storyboardPath)!.add(storyboardName);
339
- }
340
-
341
- // For each potential storyboard directory, check if it has a canvas
342
- for (const [storyboardPath, storyboardNames] of storyboardDirs) {
343
- for (const storyboardName of storyboardNames) {
344
- // Skip __executions__ directory (legacy pattern, should not exist)
345
- if (storyboardName === '__executions__') continue;
346
-
347
- // Find canvas for this storyboard
348
- const storyboardCanvas = canvases.find(c => {
349
- const canvasDir = c.path.split('/').slice(0, -1).join('/');
350
- return canvasDir === storyboardPath && c.basename === storyboardName;
351
- });
352
-
353
- if (!storyboardCanvas) continue;
354
-
355
- // This is a storyboard! Now discover workflows
356
- const workflows = await this.discoverWorkflowsInStoryboard(
357
- fileTree,
358
- storyboardPath,
359
- storyboardName,
360
- packageMap,
361
- options,
362
- spanLookup,
363
- scopeLabelLookup,
364
- errors
365
- );
366
-
367
- // Determine package context
368
- const packageInfo = this.findPackageForPath(storyboardPath, packageMap);
369
-
370
- // Generate unique ID
371
- const id = packageInfo
372
- ? `${packageInfo.packageData.name}/${storyboardName}`
373
- : storyboardName;
374
-
375
- // Create discovered storyboard
376
- const storyboard: DiscoveredStoryboard | DiscoveredStoryboardWithContent = {
377
- id,
378
- name: this.toDisplayName(storyboardName),
379
- path: storyboardPath,
380
- basename: storyboardName,
381
- canvas: storyboardCanvas,
382
- workflows,
383
- packageName: packageInfo?.packageData.name,
384
- packagePath: packageInfo?.packageData.path,
385
- scope: packageInfo ? 'package' : 'root',
386
- };
387
-
388
- storyboards.push(storyboard);
389
- }
390
- }
391
-
392
- // Add standalone canvas files (flat structure without workflows)
393
- // These are typically .canvas files used for documentation/architecture diagrams
394
- const storyboardCanvasIds = new Set(storyboards.map(s => s.canvas.id));
395
-
396
- for (const canvas of canvases) {
397
- // Skip if already part of a hierarchical storyboard
398
- if (storyboardCanvasIds.has(canvas.id)) continue;
399
-
400
- // Check if canvas is in flat structure (.principal-views/file.canvas)
401
- const canvasDir = canvas.path.split('/').slice(0, -1).join('/');
402
- const parts = canvasDir.split('/');
403
- const pvIndex = parts.indexOf(CanvasDiscovery.CANVAS_DIR);
404
-
405
- // Only include flat .canvas files (for documentation)
406
- // Exclude .otel.canvas files which must use storyboard structure
407
- if (pvIndex !== -1 && parts.length === pvIndex + 1 && canvas.type !== 'otel') {
408
- const packageInfo = this.findPackageForPath(canvas.path, packageMap);
409
-
410
- // Create a standalone storyboard with no workflows
411
- const storyboard: DiscoveredStoryboard | DiscoveredStoryboardWithContent = {
412
- id: canvas.id,
413
- name: canvas.name,
414
- path: canvasDir,
415
- basename: canvas.basename,
416
- canvas: canvas,
417
- workflows: [], // No workflows for standalone canvases
418
- packageName: packageInfo?.packageData.name,
419
- packagePath: packageInfo?.packageData.path,
420
- scope: packageInfo ? 'package' : 'root',
421
- };
422
-
423
- storyboards.push(storyboard);
424
- }
425
- }
426
-
427
- return storyboards;
428
- }
429
-
430
- /**
431
- * Discover workflows within a storyboard folder
432
- */
433
- private async discoverWorkflowsInStoryboard(
434
- fileTree: FileTree,
435
- storyboardPath: string,
436
- storyboardName: string,
437
- packageMap: Map<string, PackageLayer>,
438
- options: DiscoveryOptions,
439
- spanLookup: SpanLookup,
440
- scopeLabelLookup: ScopeLabelLookup,
441
- errors: Array<{ path: string; error: string }>
442
- ): Promise<(DiscoveredWorkflow | DiscoveredWorkflowWithContent)[]> {
443
- const workflows: (DiscoveredWorkflow | DiscoveredWorkflowWithContent)[] = [];
444
-
445
- // Find all workflow files in this storyboard
446
- for (const file of fileTree.allFiles) {
447
- const path = file.relativePath || file.path || '';
448
-
449
- // Check if file is in this storyboard
450
- if (!path.startsWith(storyboardPath + '/')) continue;
451
-
452
- // Check if it's a workflow file
453
- if (!path.endsWith(CanvasDiscovery.WORKFLOW_EXTENSION)) continue;
454
-
455
- // Extract workflow info
456
- const filename = path.split('/').pop();
457
- if (!filename) continue;
458
-
459
- const basename = filename.replace(CanvasDiscovery.WORKFLOW_EXTENSION, '');
460
- const workflowDir = path.split('/').slice(0, -1).join('/');
461
-
462
- // Determine package context
463
- const packageInfo = this.findPackageForPath(path, packageMap);
464
-
465
- // Generate unique ID (basename only - storyboard context is in storyboardId)
466
- const id = basename;
467
-
468
- // Discover test traces co-located in the same directory as workflow.json
469
- const workflowTestTraces = await this.discoverTestTracesInWorkflowDir(
470
- fileTree,
471
- workflowDir,
472
- packageMap,
473
- options,
474
- errors
475
- );
476
-
477
- // Create discovered workflow
478
- let workflow: DiscoveredWorkflow | DiscoveredWorkflowWithContent = {
479
- id,
480
- name: this.toDisplayName(basename),
481
- path,
482
- basename,
483
- storyboardId: packageInfo
484
- ? `${packageInfo.packageData.name}/${storyboardName}`
485
- : storyboardName,
486
- packageName: packageInfo?.packageData.name,
487
- packagePath: packageInfo?.packageData.path,
488
- scope: packageInfo ? 'package' : 'root',
489
- testTraces: workflowTestTraces,
490
- };
491
-
492
- // Optionally load content
493
- if (options.includeContent && options.fileReader) {
494
- try {
495
- const content = await options.fileReader(path);
496
- const parsedContent = JSON.parse(content);
497
-
498
- // Extract referenced spans from workflow content
499
- const edgeResult = deriveWorkflowEdges(parsedContent, path);
500
-
501
- // Convert span patterns to ReferencedSpan objects with labels and scopes
502
- const referencedSpans: ReferencedSpan[] = edgeResult.referencedSpans.map(
503
- (pattern) => {
504
- const spanInfo = spanLookup.get(pattern);
505
- return {
506
- pattern,
507
- label: spanInfo?.label,
508
- scope: spanInfo?.scope,
509
- };
510
- }
511
- );
512
-
513
- // Derive workflow instrumentation scope from rootSpan's scope
514
- const rootSpan = parsedContent.rootSpan as string | undefined;
515
- const rootSpanInfo = rootSpan ? spanLookup.get(rootSpan) : undefined;
516
- const instrumentationScope = rootSpanInfo?.scope;
517
- const instrumentationScopeLabel = instrumentationScope
518
- ? scopeLabelLookup.get(instrumentationScope)
519
- : undefined;
520
-
521
- workflow = {
522
- ...workflow,
523
- content: parsedContent,
524
- referencedSpans,
525
- instrumentationScope,
526
- instrumentationScopeLabel,
527
- } as DiscoveredWorkflowWithContent;
528
- } catch (error) {
529
- errors.push({
530
- path,
531
- error: `Failed to parse workflow content: ${(error as Error).message}`,
532
- });
533
- }
534
- }
535
-
536
- workflows.push(workflow);
537
- }
538
-
539
- return workflows;
540
- }
541
-
542
- /**
543
- * Discover execution files co-located in a workflow directory
544
- */
545
- private async discoverTestTracesInWorkflowDir(
546
- fileTree: FileTree,
547
- workflowDir: string,
548
- packageMap: Map<string, PackageLayer>,
549
- options: DiscoveryOptions,
550
- errors: Array<{ path: string; error: string }>
551
- ): Promise<(DiscoveredTestTrace | DiscoveredTestTraceWithContent)[]> {
552
- const testTraces: (DiscoveredTestTrace | DiscoveredTestTraceWithContent)[] = [];
553
-
554
- // Find all .otel.json files in the workflow directory
555
- for (const file of fileTree.allFiles) {
556
- const path = file.relativePath || file.path || '';
557
-
558
- // Check if file is in this workflow directory
559
- const fileDir = path.split('/').slice(0, -1).join('/');
560
- if (fileDir !== workflowDir) continue;
561
-
562
- // Check if it's a test trace file (.otel.json)
563
- if (!path.endsWith('.otel.json')) {
564
- continue;
565
- }
566
-
567
- // Extract test trace metadata
568
- const filename = path.split('/').pop();
569
- if (!filename) continue;
570
-
571
- const basename = filename.replace('.otel.json', '');
572
-
573
- // Determine package context
574
- const packageInfo = this.findPackageForPath(path, packageMap);
575
-
576
- // Generate unique ID (workflow-scoped)
577
- const workflowBasename = workflowDir.split('/').pop() || '';
578
- const id = packageInfo
579
- ? `${packageInfo.packageData.name}/${workflowBasename}/${basename}`
580
- : `${workflowBasename}/${basename}`;
581
-
582
- // Create discovered test trace
583
- let testTrace: DiscoveredTestTrace | DiscoveredTestTraceWithContent = {
584
- id,
585
- name: this.toDisplayName(basename),
586
- path,
587
- basename,
588
- type: 'otel',
589
- canvasBasename: basename, // For backward compatibility
590
- packageName: packageInfo?.packageData.name,
591
- packagePath: packageInfo?.packageData.path,
592
- scope: packageInfo ? 'package' : 'root',
593
- };
594
-
595
- // Optionally load content
596
- if (options.includeContent && options.fileReader) {
597
- try {
598
- const content = await options.fileReader(path);
599
- testTrace = { ...testTrace, content: JSON.parse(content) } as DiscoveredTestTraceWithContent;
600
- } catch (error) {
601
- errors.push({
602
- path,
603
- error: `Failed to parse test trace content: ${(error as Error).message}`,
604
- });
605
- }
606
- }
607
-
608
- testTraces.push(testTrace);
609
- }
610
-
611
- return testTraces;
612
- }
613
-
614
- /**
615
- * Discover packages with caching by fileTree SHA
616
- */
617
- private async discoverPackagesWithCache(
618
- fileTree: FileTree,
619
- fileReader?: (path: string) => Promise<string>
620
- ): Promise<PackageLayer[]> {
621
- const cacheKey = fileTree.sha;
622
-
623
- if (this.packageCache.has(cacheKey)) {
624
- return this.packageCache.get(cacheKey)!;
625
- }
626
-
627
- const packages = await this.packageModule.discoverPackages(fileTree, fileReader);
628
- this.packageCache.set(cacheKey, packages);
629
-
630
- return packages;
631
- }
632
-
633
- /**
634
- * Build package lookup map for efficient path matching
635
- */
636
- private buildPackageMap(packages: PackageLayer[]): Map<string, PackageLayer> {
637
- const map = new Map<string, PackageLayer>();
638
-
639
- for (const pkg of packages) {
640
- // Normalize package path for lookup (replace backslashes with forward slashes)
641
- const normalizedPath = pkg.packageData.path.replace(/\\/g, '/');
642
- map.set(normalizedPath, pkg);
643
- }
644
-
645
- return map;
646
- }
647
-
648
- /**
649
- * Discover canvas files in the file tree
650
- */
651
- private async discoverCanvasFiles(
652
- fileTree: FileTree,
653
- packageMap: Map<string, PackageLayer>,
654
- options: DiscoveryOptions,
655
- errors: Array<{ path: string; error: string }>
656
- ): Promise<DiscoveredCanvas[]> {
657
- const canvases: DiscoveredCanvas[] = [];
658
-
659
- for (const file of fileTree.allFiles) {
660
- const path = file.relativePath || file.path || '';
661
-
662
- // Check if in .principal-views directory
663
- if (!this.isInCanvasDir(path)) continue;
664
-
665
- // Extract canvas metadata
666
- const metadata = this.parseCanvasPath(path);
667
- if (!metadata) continue;
668
-
669
- // Determine package context
670
- const packageInfo = this.findPackageForPath(path, packageMap);
671
-
672
- // Generate unique ID
673
- // Include canvas type suffix for non-regular types to avoid collisions
674
- // e.g., "architecture" vs "architecture.scopes"
675
- const idSuffix = metadata.type !== 'regular' ? `.${metadata.type}` : '';
676
- const id = packageInfo
677
- ? `${packageInfo.packageData.name}/${metadata.basename}${idSuffix}`
678
- : `${metadata.basename}${idSuffix}`;
679
-
680
- // Create discovered canvas
681
- const canvas: DiscoveredCanvas = {
682
- id,
683
- name: this.toDisplayName(metadata.basename),
684
- path,
685
- basename: metadata.basename,
686
- type: metadata.type,
687
- packageName: packageInfo?.packageData.name,
688
- packagePath: packageInfo?.packageData.path,
689
- scope: packageInfo ? 'package' : 'root',
690
- };
691
-
692
- // Optionally load content
693
- if (options.includeContent && options.fileReader) {
694
- try {
695
- const content = await options.fileReader(path);
696
- const parsedContent = JSON.parse(content);
697
-
698
- // Cast to DiscoveredCanvasWithContent when adding content
699
- const canvasWithContent = canvas as DiscoveredCanvasWithContent;
700
- canvasWithContent.content = parsedContent;
701
-
702
- // Validate OTEL canvas nodes for explicit color usage (only for .otel.canvas files)
703
- if (metadata.type === 'otel') {
704
- const otelValidator = new OtelCanvasValidator();
705
- const violations = otelValidator.validate(parsedContent, path);
706
-
707
- for (const violation of violations) {
708
- errors.push({
709
- path: violation.file,
710
- error: `[${violation.ruleId}] ${violation.message}. ${violation.impact} ${violation.suggestion}`,
711
- });
712
- }
713
- }
714
-
715
- // Extract markdown path from canvas metadata if it exists
716
- if (parsedContent.markdown) {
717
- canvas.markdownPath = parsedContent.markdown;
718
- }
719
- } catch (error) {
720
- errors.push({
721
- path,
722
- error: `Failed to parse canvas content: ${(error as Error).message}`,
723
- });
724
- }
725
- }
726
-
727
- canvases.push(canvas);
728
- }
729
-
730
- return canvases;
731
- }
732
-
733
- /**
734
- * Discover execution files in the file tree
735
- */
736
- /**
737
- * Check if path is in .principal-views directory
738
- * Supports both flat (.principal-views/file.canvas) and hierarchical (.principal-views/storyboard/file.canvas) structures
739
- */
740
- private isInCanvasDir(path: string): boolean {
741
- const parts = path.split('/');
742
-
743
- // Root flat: .principal-views/file.canvas (2 parts)
744
- if (parts[0] === CanvasDiscovery.CANVAS_DIR && parts.length === 2) {
745
- return true;
746
- }
747
-
748
- // Root hierarchical: .principal-views/storyboard/file.canvas (3 parts)
749
- if (parts[0] === CanvasDiscovery.CANVAS_DIR && parts.length === 3) {
750
- return true;
751
- }
752
-
753
- // Package structures
754
- if (parts.includes(CanvasDiscovery.CANVAS_DIR)) {
755
- const idx = parts.indexOf(CanvasDiscovery.CANVAS_DIR);
756
- // Package flat: packages/subsystems-core/.principal-views/file.canvas (idx + 2 parts)
757
- // Package hierarchical: packages/subsystems-core/.principal-views/storyboard/file.canvas (idx + 3 parts)
758
- return parts.length === idx + 2 || parts.length === idx + 3;
759
- }
760
-
761
- return false;
762
- }
763
-
764
- /**
765
- * Parse canvas file path to extract metadata
766
- */
767
- private parseCanvasPath(path: string): { basename: string; type: CanvasType } | null {
768
- const filename = path.split('/').pop();
769
- if (!filename) return null;
770
-
771
- // Check for .scopes.canvas first (must come before .canvas check)
772
- if (filename.endsWith('.scopes.canvas')) {
773
- return {
774
- basename: filename.replace(/\.scopes\.canvas$/, ''),
775
- type: 'scopes',
776
- };
777
- }
778
-
779
- // Check for .resources.canvas (must come before .canvas check)
780
- if (filename.endsWith('.resources.canvas')) {
781
- return {
782
- basename: filename.replace(/\.resources\.canvas$/, ''),
783
- type: 'resources',
784
- };
785
- }
786
-
787
- // Check for .spans.canvas (must come before .canvas check)
788
- if (filename.endsWith('.spans.canvas')) {
789
- return {
790
- basename: filename.replace(/\.spans\.canvas$/, ''),
791
- type: 'spans',
792
- };
793
- }
794
-
795
- // Check for .events.canvas (must come before .canvas check)
796
- if (filename.endsWith('.events.canvas')) {
797
- return {
798
- basename: filename.replace(/\.events\.canvas$/, ''),
799
- type: 'events',
800
- };
801
- }
802
-
803
- // Check for .otel.canvas (must come before .canvas check)
804
- if (filename.endsWith('.otel.canvas')) {
805
- return {
806
- basename: filename.replace(/\.otel\.canvas$/, ''),
807
- type: 'otel',
808
- };
809
- }
810
-
811
- // Check for .canvas (but not .otel.canvas, .scopes.canvas, .resources.canvas, .spans.canvas, or .events.canvas)
812
- if (filename.endsWith('.canvas')) {
813
- const basename = filename.replace(/\.canvas$/, '');
814
-
815
- // Handle special case: files named exactly "resources.canvas" or "spans.canvas"
816
- // These are architecture canvases despite using .canvas extension
817
- if (basename === 'resources') {
818
- return { basename, type: 'resources' };
819
- }
820
- if (basename === 'spans') {
821
- return { basename, type: 'spans' };
822
- }
823
- if (basename === 'scopes') {
824
- return { basename, type: 'scopes' };
825
- }
826
- if (basename === 'events') {
827
- return { basename, type: 'events' };
828
- }
829
-
830
- return { basename, type: 'regular' };
831
- }
832
-
833
- return null;
834
- }
835
-
836
- /**
837
- * Find package for a given path using longest-path matching
838
- */
839
- private findPackageForPath(
840
- path: string,
841
- packageMap: Map<string, PackageLayer>
842
- ): PackageLayer | null {
843
- // Find the longest matching package path
844
- let bestMatch: PackageLayer | null = null;
845
- let bestMatchLength = 0;
846
-
847
- for (const [pkgPath, pkg] of packageMap) {
848
- if (path.startsWith(pkgPath + '/')) {
849
- if (pkgPath.length > bestMatchLength) {
850
- bestMatch = pkg;
851
- bestMatchLength = pkgPath.length;
852
- }
853
- }
854
- }
855
-
856
- return bestMatch;
857
- }
858
-
859
- /**
860
- * Convert basename to display name (Title Case)
861
- */
862
- private toDisplayName(basename: string): string {
863
- return basename
864
- .split('-')
865
- .map(word => word.charAt(0).toUpperCase() + word.slice(1))
866
- .join(' ');
867
- }
868
-
869
- /**
870
- * Sort by package then name
871
- */
872
- private compareByPackageThenName(
873
- a: DiscoveredCanvas | DiscoveredTestTrace | DiscoveredStoryboard | DiscoveredDashboard,
874
- b: DiscoveredCanvas | DiscoveredTestTrace | DiscoveredStoryboard | DiscoveredDashboard
875
- ): number {
876
- // Package files first, then root
877
- if (a.packageName && !b.packageName) return -1;
878
- if (!a.packageName && b.packageName) return 1;
879
-
880
- // If both have packages, sort by package name
881
- if (a.packageName && b.packageName) {
882
- const pkgCompare = a.packageName.localeCompare(b.packageName);
883
- if (pkgCompare !== 0) return pkgCompare;
884
- }
885
-
886
- // Within same package/root, sort by name
887
- return a.name.localeCompare(b.name);
888
- }
889
-
890
- /**
891
- * Validate required canvas types based on dependency chain:
892
- * - resources.canvas is required (foundation)
893
- * - spans.canvas is required when resources.canvas exists
894
- * - .otel.canvas is required when spans.canvas exists
895
- */
896
- private validateRequiredCanvases(
897
- canvases: DiscoveredCanvas[],
898
- storyboards: (DiscoveredStoryboard | DiscoveredStoryboardWithContent)[],
899
- errors: Array<{ path: string; error: string }>
900
- ): void {
901
- // Check canvas types by category
902
- const hasResourcesCanvas = canvases.some(c => c.type === 'resources');
903
- const hasSpansCanvas = canvases.some(c => c.type === 'spans');
904
- // Check for otel canvases specifically (not just any storyboard, since standalone canvases also create storyboards)
905
- const hasOtelCanvas = canvases.some(c => c.type === 'otel');
906
-
907
- // If no canvases at all, nothing to validate (no .principal-views directory)
908
- if (canvases.length === 0 && storyboards.length === 0) {
909
- return;
910
- }
911
-
912
- // 1. resources.canvas is required (foundation)
913
- if (!hasResourcesCanvas) {
914
- errors.push({
915
- path: '.principal-views',
916
- error:
917
- 'Missing required resources.canvas: A resources canvas documenting OTEL resources and scopes is required. ' +
918
- 'Create .principal-views/resources.canvas (or architecture.resources.canvas) with nodes showing service.name and instrumentation scopes.',
919
- });
920
- // Don't check further dependencies if foundation is missing
921
- return;
922
- }
923
-
924
- // 2. spans.canvas is required when resources.canvas exists
925
- if (!hasSpansCanvas) {
926
- errors.push({
927
- path: '.principal-views',
928
- error:
929
- 'Missing required spans.canvas: When resources.canvas exists, a spans canvas documenting span conventions is required. ' +
930
- 'Create .principal-views/architecture.spans.canvas with nodes for each span pattern (e.g., validate.*, http.request) and edges showing valid parent-child relationships.',
931
- });
932
- // Don't check further dependencies
933
- return;
934
- }
935
-
936
- // 3. .otel.canvas is required when spans.canvas exists
937
- if (!hasOtelCanvas) {
938
- errors.push({
939
- path: '.principal-views',
940
- error:
941
- 'Missing required .otel.canvas: When spans.canvas exists, at least one feature-level OTEL canvas is required. ' +
942
- 'Create a storyboard with an .otel.canvas file (e.g., .principal-views/my-feature/my-feature.otel.canvas) documenting events for a specific feature.',
943
- });
944
- }
945
- }
946
-
947
- /**
948
- * Discover dashboard files from .principal-views/dashboards/ folder
949
- */
950
- private async discoverDashboards(
951
- fileTree: FileTree,
952
- packageMap: Map<string, PackageLayer>,
953
- options: DiscoveryOptions,
954
- errors: Array<{ path: string; error: string }>
955
- ): Promise<(DiscoveredDashboard | DiscoveredDashboardWithContent)[]> {
956
- const dashboards: (DiscoveredDashboard | DiscoveredDashboardWithContent)[] = [];
957
-
958
- for (const file of fileTree.allFiles) {
959
- const path = file.relativePath || file.path || '';
960
-
961
- // Only look for .dashboard.json files in dashboards/ folder
962
- if (!path.endsWith(CanvasDiscovery.DASHBOARD_EXTENSION)) continue;
963
-
964
- // Must be in .principal-views/dashboards/ folder
965
- const parts = path.split('/');
966
- const pvIndex = parts.indexOf(CanvasDiscovery.CANVAS_DIR);
967
- if (pvIndex === -1) continue;
968
-
969
- // Check if it's in the dashboards/ folder (directly after .principal-views/)
970
- const nextPart = parts[pvIndex + 1];
971
- if (nextPart !== 'dashboards') continue;
972
-
973
- const filename = parts[parts.length - 1];
974
- const basename = filename.replace(/\.dashboard\.json$/, '');
975
-
976
- // Determine package context
977
- const packageInfo = this.findPackageForPath(path, packageMap);
978
-
979
- // Generate unique ID
980
- const id = packageInfo
981
- ? `${packageInfo.packageData.name}/${basename}`
982
- : basename;
983
-
984
- const dashboard: DiscoveredDashboard = {
985
- id,
986
- name: this.toDisplayName(basename),
987
- path,
988
- basename,
989
- packageName: packageInfo?.packageData.name,
990
- packagePath: packageInfo?.packageData.path,
991
- scope: packageInfo ? 'package' : 'root',
992
- };
993
-
994
- // Optionally load content
995
- if (options.includeContent && options.fileReader) {
996
- try {
997
- const content = await options.fileReader(path);
998
- const parsed = JSON.parse(content);
999
- (dashboard as DiscoveredDashboardWithContent).content = parsed;
1000
- } catch (e) {
1001
- errors.push({
1002
- path,
1003
- error: `Failed to parse dashboard: ${e instanceof Error ? e.message : String(e)}`,
1004
- });
1005
- }
1006
- }
1007
-
1008
- dashboards.push(dashboard);
1009
- }
1010
-
1011
- return dashboards;
1012
- }
1013
-
1014
- /**
1015
- * Detect legacy flat canvas structures and add deprecation errors
1016
- * Note: Flat .canvas and .scopes.canvas files are supported
1017
- * Only .otel.canvas files in flat structure are deprecated
1018
- */
1019
- private detectLegacyStructures(
1020
- canvases: DiscoveredCanvas[],
1021
- storyboards: (DiscoveredStoryboard | DiscoveredStoryboardWithContent)[],
1022
- errors: Array<{ path: string; error: string }>
1023
- ): void {
1024
- // Build a set of storyboard canvas IDs for quick lookup
1025
- const storyboardCanvasIds = new Set(storyboards.map(s => s.canvas.id));
1026
-
1027
- // Check for legacy flat .otel.canvas files (not part of any storyboard)
1028
- // Note: Flat .canvas and .scopes.canvas files are supported
1029
- for (const canvas of canvases) {
1030
- if (!storyboardCanvasIds.has(canvas.id)) {
1031
- // This canvas is not part of any storyboard
1032
- const canvasDir = canvas.path.split('/').slice(0, -1).join('/');
1033
- const parts = canvasDir.split('/');
1034
- const pvIndex = parts.indexOf(CanvasDiscovery.CANVAS_DIR);
1035
-
1036
- // Only error if it's a .otel.canvas file in flat structure
1037
- // Regular .canvas and .scopes.canvas files in flat structure are supported
1038
- if (pvIndex !== -1 && parts.length === pvIndex + 1 && canvas.type === 'otel') {
1039
- errors.push({
1040
- path: canvas.path,
1041
- error: 'DEPRECATED: Flat .otel.canvas files are no longer supported. .otel.canvas files must use the storyboard structure (.principal-views/storyboard-name/storyboard-name.otel.canvas). For static documentation, use .canvas files instead.',
1042
- });
1043
- }
1044
- }
1045
- }
1046
- }
1047
-
1048
- /**
1049
- * Validate scope hierarchy for hierarchical filtering
1050
- *
1051
- * Validates:
1052
- * 1. Workflow rootSpan exists in spans.canvas
1053
- * 2. Span conventions have otel.scope defined
1054
- * 3. Scope references exist in scopes.canvas (warning)
1055
- */
1056
- private validateScopeHierarchy(
1057
- storyboards: (DiscoveredStoryboard | DiscoveredStoryboardWithContent)[],
1058
- spanLookup: SpanLookup,
1059
- scopeLabelLookup: ScopeLabelLookup,
1060
- errors: Array<{ path: string; error: string }>
1061
- ): void {
1062
- // Track scopes that have been warned about (to avoid duplicate warnings)
1063
- const warnedScopes = new Set<string>();
1064
-
1065
- for (const storyboard of storyboards) {
1066
- // Only validate otel storyboards
1067
- if (storyboard.canvas.type !== 'otel') continue;
1068
-
1069
- for (const workflow of storyboard.workflows) {
1070
- const workflowWithContent = workflow as DiscoveredWorkflowWithContent;
1071
- const content = workflowWithContent.content;
1072
- if (!content) continue;
1073
-
1074
- const rootSpan = content.rootSpan as string | undefined;
1075
- if (!rootSpan) continue;
1076
-
1077
- // 1. Validate rootSpan exists in spans.canvas
1078
- const rootSpanInfo = spanLookup.get(rootSpan);
1079
- if (!rootSpanInfo) {
1080
- errors.push({
1081
- path: workflow.path,
1082
- error:
1083
- `Workflow "${workflow.basename}" has rootSpan "${rootSpan}" but no matching span convention ` +
1084
- `was found in spans.canvas. Add an otel-span-convention node with spanPattern: "${rootSpan}".`,
1085
- });
1086
- continue; // Skip further validation for this workflow
1087
- }
1088
-
1089
- // 2. Validate span convention has otel.scope defined
1090
- if (!rootSpanInfo.scope) {
1091
- errors.push({
1092
- path: workflow.path,
1093
- error:
1094
- `Span convention "${rootSpan}" in spans.canvas does not declare a scope. ` +
1095
- `Add otel.scope to specify which instrumentation scope creates this span.`,
1096
- });
1097
- continue; // Skip further validation for this workflow
1098
- }
1099
-
1100
- // 3. Warn if scope doesn't exist in scopes.canvas
1101
- const scopeName = rootSpanInfo.scope;
1102
- if (!scopeLabelLookup.has(scopeName) && !warnedScopes.has(scopeName)) {
1103
- warnedScopes.add(scopeName);
1104
- errors.push({
1105
- path: workflow.path,
1106
- error:
1107
- `Span convention "${rootSpan}" references scope "${scopeName}" but no matching ` +
1108
- `otel-scope node was found in scopes.canvas. Consider adding it for documentation.`,
1109
- });
1110
- }
1111
- }
1112
- }
1113
- }
1114
- }