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
@@ -11,7 +11,42 @@ module Archsight::Web::API; end
11
11
  module Archsight::Web::API::Docs
12
12
  extend Sinatra::Extension
13
13
 
14
- get "/api/docs" do
15
- erb :api_docs
14
+ get "/docs/api" do
15
+ serve_vue
16
+ end
17
+
18
+ # GET /api/v1/docs/resources/:filename — auto-generated resource docs
19
+ get "/api/v1/docs/resources/:filename" do
20
+ filename = params["filename"].gsub(/[^a-zA-Z0-9_-]/, "")
21
+ kind_name = filename.split("_").map(&:capitalize).join
22
+
23
+ begin
24
+ content = Archsight::Documentation.generate(kind_name)
25
+ content_type :html
26
+ "<article>#{markdown(content)}</article>"
27
+ rescue StandardError
28
+ halt 404, "Documentation not found"
29
+ end
30
+ end
31
+
32
+ # GET /api/v1/docs/:filename — static markdown/ERB docs
33
+ get "/api/v1/docs/:filename" do
34
+ filename = params["filename"].gsub(/[^a-zA-Z0-9_-]/, "")
35
+
36
+ doc_dir = File.expand_path("../../../../docs", __dir__)
37
+ erb_path = File.join(doc_dir, "#{filename}.md.erb")
38
+ md_path = File.join(doc_dir, "#{filename}.md")
39
+
40
+ content = if File.exist?(erb_path)
41
+ template = ERB.new(File.read(erb_path))
42
+ template.result(binding)
43
+ elsif File.exist?(md_path)
44
+ File.read(md_path)
45
+ else
46
+ halt 404, "Documentation not found"
47
+ end
48
+
49
+ content_type :html
50
+ "<article>#{markdown(content)}</article>"
16
51
  end
17
52
  end
@@ -22,12 +22,19 @@ module Archsight::Web::API::JsonHelpers
22
22
  end
23
23
 
24
24
  def resource_summary(resource, output:, omit_kind: false)
25
- case output
26
- when "brief"
27
- Archsight::MCP.brief_summary(resource, omit_kind: omit_kind)
28
- else # "complete"
29
- Archsight::MCP.complete_summary(resource, omit_kind: omit_kind)
30
- end
25
+ result = case output
26
+ when "brief"
27
+ Archsight::MCP.brief_summary(resource, omit_kind: omit_kind)
28
+ when "annotations"
29
+ Archsight::MCP.annotations_summary(resource, omit_kind: omit_kind)
30
+ else # "complete"
31
+ summary = Archsight::MCP.complete_summary(resource, omit_kind: omit_kind)
32
+ summary[:spec] = serialize_spec(summary[:spec]) if summary[:spec]
33
+ summary
34
+ end
35
+ result[:icon] = resource.class.icon
36
+ result[:layer] = resource.class.layer
37
+ result
31
38
  end
32
39
 
33
40
  def paginate(collection, limit:, offset:)
@@ -76,17 +83,29 @@ module Archsight::Web::API::JsonHelpers
76
83
  }
77
84
  end
78
85
 
86
+ MARKDOWN_ANNOTATION_KEYS = Set["architecture/description"].freeze
87
+
79
88
  def build_instance_response(kind, instance)
80
89
  {
81
90
  kind: kind,
82
91
  name: instance.name,
83
- metadata: { annotations: instance.annotations },
92
+ metadata: { annotations: render_annotations(instance.annotations) },
84
93
  spec: serialize_spec(instance.spec),
85
94
  relations: extract_relations(instance),
86
95
  references: extract_references(instance)
87
96
  }
88
97
  end
89
98
 
99
+ def render_annotations(annotations)
100
+ annotations.each_with_object({}) do |(key, value), result|
101
+ result[key] = if MARKDOWN_ANNOTATION_KEYS.include?(key) && value.is_a?(String)
102
+ markdown(value)
103
+ else
104
+ value
105
+ end
106
+ end
107
+ end
108
+
90
109
  def serialize_spec(spec)
91
110
  spec.transform_values do |kinds|
92
111
  next kinds unless kinds.is_a?(Hash)
@@ -110,15 +129,14 @@ module Archsight::Web::API::JsonHelpers
110
129
  }
111
130
  end
112
131
 
113
- def build_search_response(query, results, parsed_query, query_time_ms)
132
+ def build_search_response(query, results, _parsed_query, query_time_ms)
114
133
  limit, offset = parse_pagination_params
115
134
  output = parse_output_param
116
- omit_kind = !parsed_query.kind_filter.nil?
117
135
  sorted = results.sort_by(&:name)
118
136
  pagination = paginate(sorted, limit: limit, offset: offset)
119
137
 
120
138
  instances = pagination[:items].map do |r|
121
- resource_summary(r, output: output, omit_kind: omit_kind)
139
+ resource_summary(r, output: output, omit_kind: false)
122
140
  end
123
141
 
124
142
  {
@@ -135,17 +153,65 @@ module Archsight::Web::API::JsonHelpers
135
153
  def extract_relations(instance)
136
154
  relations = {}
137
155
 
138
- instance.class.relations.each do |verb, kind_name, _|
139
- rels = instance.relations(verb, kind_name).map(&:name)
156
+ instance.class.relations.each do |verb, spec_key, kind|
157
+ rels = instance.relations(verb, spec_key).map(&:name)
140
158
  next if rels.empty?
141
159
 
142
160
  relations[verb] ||= {}
143
- relations[verb][kind_name] = rels
161
+ relations[verb][kind] = rels
144
162
  end
145
163
 
146
164
  relations
147
165
  end
148
166
 
167
+ def build_filters_response(kind)
168
+ db.filters_for_kind(kind).map do |annotation, values|
169
+ {
170
+ key: annotation.key,
171
+ title: annotation.title,
172
+ description: annotation.description,
173
+ filter_type: annotation.filter.to_s,
174
+ values: values
175
+ }
176
+ end
177
+ end
178
+
179
+ def build_analysis_result(result)
180
+ data = {
181
+ name: result.name,
182
+ success: result.success?,
183
+ has_findings: result.has_findings?,
184
+ duration: result.duration,
185
+ sections: result.sections.map { |s| serialize_analysis_section(s) }
186
+ }
187
+
188
+ if result.failed?
189
+ data[:error] = result.error
190
+ data[:error_backtrace] = result.error_backtrace if result.error_backtrace&.any?
191
+ end
192
+
193
+ data
194
+ end
195
+
196
+ def serialize_analysis_section(section)
197
+ case section[:type]
198
+ when :heading
199
+ { type: "heading", level: section[:level], text: section[:text] }
200
+ when :text
201
+ { type: "text", content: section[:content] }
202
+ when :message
203
+ { type: "message", level: section[:level].to_s, message: section[:message] }
204
+ when :table
205
+ { type: "table", headers: section[:headers], rows: section[:rows] }
206
+ when :list
207
+ { type: "list", items: section[:items] }
208
+ when :code
209
+ { type: "code", lang: section[:lang], content: section[:content] }
210
+ else
211
+ { type: section[:type].to_s }
212
+ end
213
+ end
214
+
149
215
  def extract_references(instance)
150
216
  references = {}
151
217