archsight 0.1.4 → 0.2.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 (190) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +5 -4
  3. data/README.md +44 -59
  4. data/chart/archsight/Chart.yaml +6 -0
  5. data/chart/archsight/README.md +3 -0
  6. data/chart/archsight/templates/NOTES.txt +22 -0
  7. data/chart/archsight/templates/_helpers.tpl +62 -0
  8. data/chart/archsight/templates/deployment.yaml +114 -0
  9. data/chart/archsight/templates/ingress.yaml +56 -0
  10. data/chart/archsight/templates/resources-configmap.yaml +10 -0
  11. data/chart/archsight/templates/resources-pvc.yaml +23 -0
  12. data/chart/archsight/templates/service.yaml +15 -0
  13. data/chart/archsight/templates/serviceaccount.yaml +12 -0
  14. data/chart/archsight/values.yaml +162 -0
  15. data/docs/architecture.md +39 -0
  16. data/docs/docker.md +49 -0
  17. data/{lib/archsight/web/doc → docs}/import.md +10 -2
  18. data/{lib/archsight/web/doc → docs}/index.md.erb +3 -1
  19. data/docs/kubernetes.md +149 -0
  20. data/docs/licenses.md +307 -0
  21. data/lib/archsight/analysis/executor.rb +0 -10
  22. data/lib/archsight/annotations/annotation.rb +85 -36
  23. data/lib/archsight/annotations/architecture_annotations.rb +1 -34
  24. data/lib/archsight/annotations/computed.rb +1 -1
  25. data/lib/archsight/annotations/generated_annotations.rb +6 -3
  26. data/lib/archsight/annotations/git_annotations.rb +8 -4
  27. data/lib/archsight/annotations/interface_annotations.rb +35 -0
  28. data/lib/archsight/cli.rb +4 -2
  29. data/lib/archsight/editor/content_hasher.rb +37 -0
  30. data/lib/archsight/editor/file_writer.rb +79 -0
  31. data/lib/archsight/editor.rb +237 -0
  32. data/lib/archsight/graph.rb +1 -51
  33. data/lib/archsight/helpers.rb +0 -20
  34. data/lib/archsight/import/handlers/github.rb +16 -6
  35. data/lib/archsight/import/handlers/gitlab.rb +28 -10
  36. data/lib/archsight/import/handlers/repository.rb +56 -6
  37. data/lib/archsight/import/handlers/rest_api.rb +13 -1
  38. data/lib/archsight/import/license_analyzer.rb +650 -0
  39. data/lib/archsight/import/team_matcher.rb +111 -61
  40. data/lib/archsight/linter.rb +1 -1
  41. data/lib/archsight/mcp/base.rb +11 -0
  42. data/lib/archsight/mcp/execute_analysis_tool.rb +100 -0
  43. data/lib/archsight/mcp.rb +1 -0
  44. data/lib/archsight/renderer.rb +4 -4
  45. data/lib/archsight/resources/analysis.rb +1 -17
  46. data/lib/archsight/resources/application_interface.rb +1 -5
  47. data/lib/archsight/resources/base.rb +14 -14
  48. data/lib/archsight/resources/business_actor.rb +18 -3
  49. data/lib/archsight/resources/technology_artifact.rb +48 -0
  50. data/lib/archsight/resources/technology_interface.rb +1 -1
  51. data/lib/archsight/resources/technology_service.rb +5 -0
  52. data/lib/archsight/version.rb +1 -1
  53. data/lib/archsight/web/api/docs.rb +37 -2
  54. data/lib/archsight/web/api/json_helpers.rb +79 -13
  55. data/lib/archsight/web/api/openapi/spec.yaml +699 -0
  56. data/lib/archsight/web/api/routes.rb +23 -0
  57. data/lib/archsight/web/application.rb +48 -128
  58. data/lib/archsight/web/editor/form_builder.rb +100 -0
  59. data/lib/archsight/web/editor/helpers.rb +150 -0
  60. data/lib/archsight/web/editor/routes.rb +166 -0
  61. data/lib/archsight/web/public/vue/ApiDocsPage-B1RqTNqh.js +1 -0
  62. data/lib/archsight/web/public/vue/ApiDocsPage-DhNTOH4o.css +1 -0
  63. data/lib/archsight/web/public/vue/DocPage-DzwBgBd4.js +1 -0
  64. data/lib/archsight/web/public/vue/EditorPage-D_miHSv4.js +34 -0
  65. data/lib/archsight/web/public/vue/EditorPage-Dq0MuTnp.css +1 -0
  66. data/lib/archsight/web/public/vue/ErrorPage-CQQtPey3.js +2 -0
  67. data/lib/archsight/web/public/vue/ErrorPage-CwPT3JUr.css +1 -0
  68. data/lib/archsight/web/public/vue/GraphView-DRcIqAiR.css +1 -0
  69. data/lib/archsight/web/public/vue/GraphView-T9jFH_qg.js +1 -0
  70. data/lib/archsight/web/public/vue/InstanceRouter-1Sm-CRhf.js +2 -0
  71. data/lib/archsight/web/public/vue/InstanceRouter-BJkDRXZY.css +1 -0
  72. data/lib/archsight/web/public/vue/KindList-JA_L_-Cz.js +1 -0
  73. data/lib/archsight/web/public/vue/ResourceList-8iqavWdg.js +1 -0
  74. data/lib/archsight/web/public/vue/ResourceList-DP-z-j71.css +1 -0
  75. data/lib/archsight/web/public/vue/SearchResults-BGHbg48-.css +1 -0
  76. data/lib/archsight/web/public/vue/SearchResults-BdgFeHcm.js +1 -0
  77. data/lib/archsight/web/public/vue/_basePickBy-CVgieyx-.js +1 -0
  78. data/lib/archsight/web/public/vue/_baseUniq-BNfrOSaP.js +1 -0
  79. data/lib/archsight/web/public/vue/architectureDiagram-VXUJARFQ-CJXNpTr5.js +36 -0
  80. data/lib/archsight/web/public/vue/blockDiagram-VD42YOAC-B5488Hes.js +122 -0
  81. data/lib/archsight/web/public/vue/c4Diagram-YG6GDRKO-eYY3hprM.js +10 -0
  82. data/lib/archsight/web/public/vue/chunk-4BX2VUAB-ZoXeL4D1.js +1 -0
  83. data/lib/archsight/web/public/vue/chunk-55IACEB6-rNtQYnu_.js +1 -0
  84. data/lib/archsight/web/public/vue/chunk-B4BG7PRW-DolAeVV9.js +165 -0
  85. data/lib/archsight/web/public/vue/chunk-DI55MBZ5-DnN0f_hj.js +220 -0
  86. data/lib/archsight/web/public/vue/chunk-FMBD7UC4-BQWOCMuR.js +15 -0
  87. data/lib/archsight/web/public/vue/chunk-QN33PNHL-DId301Kb.js +1 -0
  88. data/lib/archsight/web/public/vue/chunk-QZHKN3VN-xbY0NLgv.js +1 -0
  89. data/lib/archsight/web/public/vue/chunk-TZMSLE5B-CgF9_37b.js +1 -0
  90. data/lib/archsight/web/public/vue/classDiagram-2ON5EDUG-jGlvI-Za.js +1 -0
  91. data/lib/archsight/web/public/vue/classDiagram-v2-WZHVMYZB-jGlvI-Za.js +1 -0
  92. data/lib/archsight/web/public/vue/clone-6iRPe1-W.js +1 -0
  93. data/lib/archsight/web/public/vue/cose-bilkent-S5V4N54A-CB9Zfu50.js +1 -0
  94. data/lib/archsight/web/public/vue/cytoscape.esm-5J0xJHOV.js +321 -0
  95. data/lib/archsight/web/public/vue/dagre-6UL2VRFP-BqkmE-LI.js +4 -0
  96. data/lib/archsight/web/public/vue/diagram-PSM6KHXK-CKBfqtw3.js +24 -0
  97. data/lib/archsight/web/public/vue/diagram-QEK2KX5R-B78rOlvK.js +43 -0
  98. data/lib/archsight/web/public/vue/diagram-S2PKOQOG-BlXC6Cia.js +24 -0
  99. data/lib/archsight/web/public/vue/erDiagram-Q2GNP2WA-BnliyziJ.js +60 -0
  100. data/lib/archsight/web/public/vue/flowDiagram-NV44I4VS-wuqPowTd.js +162 -0
  101. data/lib/archsight/web/public/vue/ganttDiagram-JELNMOA3-GSffAIH3.js +267 -0
  102. data/lib/archsight/web/public/vue/gitGraphDiagram-V2S2FVAM-OA7VyugW.js +65 -0
  103. data/lib/archsight/web/public/vue/graph-BXHAtA0S.js +1 -0
  104. data/lib/archsight/web/public/vue/graphviz-CJms5bxZ.js +13 -0
  105. data/lib/archsight/web/public/vue/index-DsEsN0_K.js +2 -0
  106. data/lib/archsight/web/public/vue/index-Tiu4C-Sb.css +1 -0
  107. data/lib/archsight/web/public/vue/infoDiagram-HS3SLOUP-nlVe2qgv.js +2 -0
  108. data/lib/archsight/web/public/vue/journeyDiagram-XKPGCS4Q-CtTIcKwf.js +139 -0
  109. data/lib/archsight/web/public/vue/kanban-definition-3W4ZIXB7-837KX0sW.js +89 -0
  110. data/lib/archsight/web/public/vue/katex-C-M49wc6.js +261 -0
  111. data/lib/archsight/web/public/vue/layout-DtE0QdL6.js +1 -0
  112. data/lib/archsight/web/public/vue/mermaid-DpPHPFQh.js +250 -0
  113. data/lib/archsight/web/public/vue/mindmap-definition-VGOIOE7T-9gLF2AoY.js +68 -0
  114. data/lib/archsight/web/public/vue/pieDiagram-ADFJNKIX-CyCNgw3u.js +30 -0
  115. data/lib/archsight/web/public/vue/quadrantDiagram-AYHSOK5B-CkPh8g02.js +7 -0
  116. data/lib/archsight/web/public/vue/requirementDiagram-UZGBJVZJ-Dkt6OSlY.js +64 -0
  117. data/lib/archsight/web/public/vue/sankeyDiagram-TZEHDZUN-BqprTk8x.js +10 -0
  118. data/lib/archsight/web/public/vue/sequenceDiagram-WL72ISMW-CTmTe1FQ.js +145 -0
  119. data/lib/archsight/web/public/vue/stateDiagram-FKZM4ZOC-CphqmkEU.js +1 -0
  120. data/lib/archsight/web/public/vue/stateDiagram-v2-4FDKWEC3-CxaDW5sW.js +1 -0
  121. data/lib/archsight/web/public/vue/timeline-definition-IT6M3QCI-CSQUZkyE.js +61 -0
  122. data/lib/archsight/web/public/vue/treemap-GDKQZRPO-DTojm7Yr.js +162 -0
  123. data/lib/archsight/web/public/{css/graph.css → vue/useGraphviz-A5s4h76R.js} +2 -1
  124. data/lib/archsight/web/public/vue/useHighlight-C6Kb5G3l.js +10 -0
  125. data/lib/archsight/web/public/vue/useMermaid-DqxTrLRB.js +1 -0
  126. data/lib/archsight/web/public/vue/usePanZoom-BybZ_rfh.js +11 -0
  127. data/lib/archsight/web/public/vue/xychartDiagram-PRI3JC2R-B1ZJZtDC.js +7 -0
  128. data/lib/archsight/web/public/vue.html +15 -0
  129. data/media/artifact.jpg +0 -0
  130. data/media/service.jpg +0 -0
  131. metadata +104 -77
  132. data/lib/archsight/web/public/css/artifact.css +0 -995
  133. data/lib/archsight/web/public/css/base.css +0 -201
  134. data/lib/archsight/web/public/css/highlight.min.css +0 -10
  135. data/lib/archsight/web/public/css/iconoir.css +0 -22
  136. data/lib/archsight/web/public/css/instance.css +0 -818
  137. data/lib/archsight/web/public/css/layout.css +0 -421
  138. data/lib/archsight/web/public/css/mermaid-layers.css +0 -188
  139. data/lib/archsight/web/public/css/pico.min.css +0 -4
  140. data/lib/archsight/web/public/img/archimate.png +0 -0
  141. data/lib/archsight/web/public/img/togaf-high-level.png +0 -0
  142. data/lib/archsight/web/public/js/graph-zoom.js +0 -18
  143. data/lib/archsight/web/public/js/highlight.min.js +0 -3899
  144. data/lib/archsight/web/public/js/htmx.min.js +0 -1
  145. data/lib/archsight/web/public/js/mermaid-init.js +0 -88
  146. data/lib/archsight/web/public/js/mermaid.min.js +0 -2811
  147. data/lib/archsight/web/public/js/sparkline.js +0 -42
  148. data/lib/archsight/web/public/js/svg-pan-zoom.min.js +0 -3
  149. data/lib/archsight/web/public/js/svg-zoom-controls.js +0 -93
  150. data/lib/archsight/web/views/api_docs.erb +0 -19
  151. data/lib/archsight/web/views/index.haml +0 -12
  152. data/lib/archsight/web/views/partials/artifact/_activity.haml +0 -55
  153. data/lib/archsight/web/views/partials/artifact/_agentic.haml +0 -25
  154. data/lib/archsight/web/views/partials/artifact/_deployment.haml +0 -29
  155. data/lib/archsight/web/views/partials/artifact/_git_info.haml +0 -16
  156. data/lib/archsight/web/views/partials/artifact/_language_stats.haml +0 -53
  157. data/lib/archsight/web/views/partials/artifact/_links.haml +0 -24
  158. data/lib/archsight/web/views/partials/artifact/_project_estimate.haml +0 -32
  159. data/lib/archsight/web/views/partials/artifact/_repositories.haml +0 -55
  160. data/lib/archsight/web/views/partials/artifact/_team.haml +0 -83
  161. data/lib/archsight/web/views/partials/artifact/_workflow.haml +0 -69
  162. data/lib/archsight/web/views/partials/components/_activity.haml +0 -37
  163. data/lib/archsight/web/views/partials/components/_git.haml +0 -17
  164. data/lib/archsight/web/views/partials/components/_jira.haml +0 -18
  165. data/lib/archsight/web/views/partials/components/_languages.haml +0 -29
  166. data/lib/archsight/web/views/partials/components/_owner.haml +0 -15
  167. data/lib/archsight/web/views/partials/components/_repositories.haml +0 -37
  168. data/lib/archsight/web/views/partials/components/_status.haml +0 -23
  169. data/lib/archsight/web/views/partials/instance/_analysis_detail.haml +0 -74
  170. data/lib/archsight/web/views/partials/instance/_analysis_result.haml +0 -64
  171. data/lib/archsight/web/views/partials/instance/_detail.haml +0 -103
  172. data/lib/archsight/web/views/partials/instance/_graph.haml +0 -6
  173. data/lib/archsight/web/views/partials/instance/_import_detail.haml +0 -87
  174. data/lib/archsight/web/views/partials/instance/_list.haml +0 -84
  175. data/lib/archsight/web/views/partials/instance/_relations.haml +0 -43
  176. data/lib/archsight/web/views/partials/instance/_requirements.haml +0 -41
  177. data/lib/archsight/web/views/partials/instance/_view_detail.haml +0 -57
  178. data/lib/archsight/web/views/partials/layout/_content.haml +0 -44
  179. data/lib/archsight/web/views/partials/layout/_error.haml +0 -22
  180. data/lib/archsight/web/views/partials/layout/_head.haml +0 -24
  181. data/lib/archsight/web/views/partials/layout/_navigation.haml +0 -21
  182. data/lib/archsight/web/views/partials/layout/_sidebar.haml +0 -27
  183. data/lib/archsight/web/views/search.haml +0 -53
  184. /data/{lib/archsight/web/doc → docs}/archimate.md +0 -0
  185. /data/{lib/archsight/web/doc → docs}/computed_annotations.md +0 -0
  186. /data/{lib/archsight/web/doc → docs}/icons.md +0 -0
  187. /data/{lib/archsight/web/doc → docs}/modeling.md +0 -0
  188. /data/{lib/archsight/web/doc → docs}/search.md +0 -0
  189. /data/{lib/archsight/web/doc → docs}/togaf.md +0 -0
  190. /data/{lib/archsight/web/doc → docs}/tool.md +0 -0
@@ -6,6 +6,7 @@ require "fileutils"
6
6
  require_relative "../handler"
7
7
  require_relative "../registry"
8
8
  require_relative "../git_analytics"
9
+ require_relative "../license_analyzer"
9
10
  require_relative "../team_matcher"
10
11
 
11
12
  # Repository handler - clones/syncs and analyzes a git repository, generates a TechnologyArtifact
@@ -18,6 +19,7 @@ require_relative "../team_matcher"
18
19
  # import/config/sccPath - Optional path to scc binary (default: scc)
19
20
  # import/config/fallbackTeam - Optional team name when no contributor match found
20
21
  # import/config/botTeam - Optional team name for bot-only repositories
22
+ # import/config/corporateAffixes - Optional comma-separated corporate username affixes for team matching (e.g., "ionos,1and1")
21
23
  class Archsight::Import::Handlers::Repository < Archsight::Import::Handler
22
24
  def execute
23
25
  @path = config("path")
@@ -70,13 +72,13 @@ class Archsight::Import::Handlers::Repository < Archsight::Import::Handler
70
72
  progress.update("Analyzing git history")
71
73
  git_data = run_git_analytics(@path)
72
74
 
73
- # Match contributors to teams
74
- progress.update("Matching teams")
75
- team_result = match_teams(git_data["top_contributors"], git_data["activity_status"])
75
+ # Analyze licenses and match teams in parallel (independent of each other)
76
+ progress.update("Analyzing licenses & matching teams")
77
+ license_data, team_result = run_license_and_team_analysis(@path, scc_data, git_data)
76
78
 
77
79
  # Build resource
78
80
  progress.update("Generating resource")
79
- resource = build_technology_artifact(@path, scc_data, git_data, team_result)
81
+ resource = build_technology_artifact(@path, scc_data, git_data, team_result, license_data)
80
82
 
81
83
  # Write output with self-marker for caching
82
84
  yaml_content = YAML.dump(resource) + YAML.dump(self_marker)
@@ -256,7 +258,8 @@ class Archsight::Import::Handlers::Repository < Archsight::Import::Handler
256
258
  def match_teams(top_contributors, activity_status)
257
259
  return nil unless database && top_contributors&.any?
258
260
 
259
- matcher = Archsight::Import::TeamMatcher.new(database)
261
+ affixes = config("corporateAffixes")&.split(",")&.map(&:strip) || []
262
+ matcher = Archsight::Import::TeamMatcher.new(database, corporate_affixes: affixes)
260
263
  result = matcher.analyze(top_contributors)
261
264
 
262
265
  # Apply fallbacks from config
@@ -272,7 +275,7 @@ class Archsight::Import::Handlers::Repository < Archsight::Import::Handler
272
275
  result
273
276
  end
274
277
 
275
- def build_technology_artifact(path, scc_data, git_data, team_result = nil)
278
+ def build_technology_artifact(path, scc_data, git_data, team_result = nil, license_data = nil)
276
279
  annotations = {}
277
280
 
278
281
  # Artifact type
@@ -295,6 +298,9 @@ class Archsight::Import::Handlers::Repository < Archsight::Import::Handler
295
298
  # Deployment annotations
296
299
  annotations.merge!(build_deployment_annotations(git_data))
297
300
 
301
+ # License annotations
302
+ annotations.merge!(build_license_annotations(license_data, visibility)) if license_data
303
+
298
304
  # Generated metadata
299
305
  annotations["generated/script"] = import_resource.name
300
306
  annotations["generated/at"] = Time.now.utc.iso8601
@@ -403,6 +409,50 @@ class Archsight::Import::Handlers::Repository < Archsight::Import::Handler
403
409
  annotations
404
410
  end
405
411
 
412
+ # Run license analysis and team matching in parallel
413
+ def run_license_and_team_analysis(path, scc_data, git_data)
414
+ languages = (scc_data["languageSummary"] || []).map { |l| l["Name"] }
415
+ license_thread = Thread.new { run_license_analysis(path, languages) }
416
+ team_result = match_teams(git_data["top_contributors"], git_data["activity_status"])
417
+ [license_thread.value, team_result]
418
+ end
419
+
420
+ def run_license_analysis(path, languages = [])
421
+ Archsight::Import::LicenseAnalyzer.new(path, languages: languages).analyze
422
+ rescue StandardError => e
423
+ progress.warn("License analysis failed: #{e.message}")
424
+ nil
425
+ end
426
+
427
+ def build_license_annotations(license_data, visibility = "internal")
428
+ annotations = {}
429
+ return annotations unless license_data
430
+
431
+ annotations["license/spdx"] = license_data["license_spdx"] if license_data["license_spdx"]
432
+ annotations["license/file"] = license_data["license_file"] if license_data["license_file"]
433
+
434
+ # Non-public repos with unknown license are de-facto proprietary
435
+ # (all-rights-reserved), not "unknown"
436
+ category = license_data["license_category"]
437
+ category = "proprietary" if category == "unknown" && !%w[public open-source].include?(visibility)
438
+ annotations["license/category"] = category if category
439
+
440
+ if license_data["dependency_count"]&.positive?
441
+ annotations["license/dependencies/count"] = license_data["dependency_count"].to_s
442
+ annotations["license/dependencies/ecosystems"] = license_data["dependency_ecosystems"] if license_data["dependency_ecosystems"]
443
+ annotations["license/dependencies/licenses"] = license_data["dependency_licenses"] if license_data["dependency_licenses"]
444
+ annotations["license/dependencies/copyleft"] = license_data["dependency_copyleft"] if license_data["dependency_copyleft"]
445
+ annotations["license/dependencies/risk"] = license_data["dependency_risk"] if license_data["dependency_risk"]
446
+
447
+ # Per-license-type counts
448
+ (license_data["dependency_license_counts"] || {}).each do |license_name, count|
449
+ annotations["license/dependencies/#{license_name}/count"] = count.to_s
450
+ end
451
+ end
452
+
453
+ annotations
454
+ end
455
+
406
456
  def build_deployment_annotations(git_data)
407
457
  annotations = {}
408
458
 
@@ -35,7 +35,7 @@ class Archsight::Import::Handlers::RestApi < Archsight::Import::Handler
35
35
  raise "Missing required config: specUrl" unless @spec_url
36
36
 
37
37
  @html_url = config("htmlUrl")
38
- @gate = config("gate", default: "GA")
38
+ @gate = normalize_gate(config("gate", default: "GA"))
39
39
 
40
40
  @interface_output_path = config("interfaceOutputPath")
41
41
  @data_object_output_path = config("dataObjectOutputPath")
@@ -79,8 +79,20 @@ class Archsight::Import::Handlers::RestApi < Archsight::Import::Handler
79
79
  write_generates_meta
80
80
  end
81
81
 
82
+ GATE_ALIASES = {
83
+ "GA" => "General-Availability",
84
+ "EA" => "Early-Access",
85
+ "DEV" => "Development"
86
+ }.freeze
87
+
82
88
  private
83
89
 
90
+ def normalize_gate(value)
91
+ GATE_ALIASES.fetch(value.upcase, value)
92
+ rescue NoMethodError
93
+ value
94
+ end
95
+
84
96
  def safe_api_name
85
97
  @name.gsub(/[^a-zA-Z0-9_-]/, "_").downcase
86
98
  end