docit 0.5.0 → 0.7.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +24 -0
- data/README.md +85 -0
- data/TROUBLESHOOTING.md +57 -0
- data/app/controllers/docit/ui_controller.rb +1 -35
- data/config/routes.rb +0 -1
- data/docs/images/scalar_image.png +0 -0
- data/docs/images/swagger_image.png +0 -0
- data/lib/docit/ai/autodoc_runner.rb +9 -4
- data/lib/docit/ai/doc_writer.rb +3 -3
- data/lib/docit/ai/groq_client.rb +4 -8
- data/lib/docit/ai/scaffold_generator.rb +3 -1
- data/lib/docit/ai/tag_injector.rb +1 -1
- data/lib/docit/ai.rb +0 -1
- data/lib/docit/builders/response_builder.rb +12 -2
- data/lib/docit/configuration.rb +13 -3
- data/lib/docit/schema_generator.rb +62 -32
- data/lib/docit/system_graph/rails_analyzer.rb +31 -4
- data/lib/docit/system_graph/source_scanner.rb +2 -3
- data/lib/docit/ui/assets/system.css +554 -0
- data/lib/docit/ui/assets/system.js +1393 -0
- data/lib/docit/ui/base_renderer.rb +12 -17
- data/lib/docit/ui/system_renderer.rb +3 -2
- data/lib/docit/ui/system_script.rb +21 -1480
- data/lib/docit/ui/system_styles.rb +5 -571
- data/lib/docit/version.rb +1 -1
- metadata +6 -2
- data/lib/docit/ai/system_insight_generator.rb +0 -127
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "json"
|
|
4
|
-
|
|
5
|
-
module Docit
|
|
6
|
-
module Ai
|
|
7
|
-
class SystemInsightGenerator
|
|
8
|
-
# mode: :nodes -> explain an arbitrary selection (diagram "AI Explain")
|
|
9
|
-
# :section -> explain one resource and how its endpoints work together
|
|
10
|
-
def initialize(graph:, selected_node_ids: [], mode: :nodes)
|
|
11
|
-
@graph = graph
|
|
12
|
-
@selected_node_ids = selected_node_ids
|
|
13
|
-
@mode = mode
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def generate
|
|
17
|
-
config = Configuration.load
|
|
18
|
-
Client.for(config).generate(prompt)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
private
|
|
22
|
-
|
|
23
|
-
attr_reader :graph, :selected_node_ids, :mode
|
|
24
|
-
|
|
25
|
-
def prompt
|
|
26
|
-
mode == :section ? section_prompt : nodes_prompt
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def nodes_prompt
|
|
30
|
-
<<~PROMPT
|
|
31
|
-
You are a senior engineer explaining a Rails system architecture to a developer. Keep your explanation extremely concise, professional, and clear. Avoid fluff, unnecessary details, or general tutorial information. Focus only on the provided components.
|
|
32
|
-
|
|
33
|
-
FORMAT YOUR RESPONSE EXACTLY LIKE THIS:
|
|
34
|
-
|
|
35
|
-
## Overview
|
|
36
|
-
A 1-2 sentence plain-English summary of what this component/action does.
|
|
37
|
-
|
|
38
|
-
## Data Flow
|
|
39
|
-
Show a simple, linear flow diagram using text and arrows (→). Keep it to 1 line if possible.
|
|
40
|
-
Example:
|
|
41
|
-
Client → GET /api/v1/users → UsersController#index → queries User model
|
|
42
|
-
|
|
43
|
-
## Connections & Interactions
|
|
44
|
-
List only the direct, relevant relationships from the graph (max 3 bullets):
|
|
45
|
-
- **Component** (type): Action details/purpose.
|
|
46
|
-
|
|
47
|
-
Do not invent or assume anything outside of the provided graph. Keep the total response under 150 words.
|
|
48
|
-
|
|
49
|
-
---
|
|
50
|
-
|
|
51
|
-
Selected node ids:
|
|
52
|
-
#{selected_node_ids.join("\n")}
|
|
53
|
-
|
|
54
|
-
Graph JSON:
|
|
55
|
-
#{JSON.pretty_generate(compact_graph)}
|
|
56
|
-
PROMPT
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def section_prompt
|
|
60
|
-
<<~PROMPT
|
|
61
|
-
You are a senior engineer writing the introduction to a section of API documentation. The section covers ONE resource and all of its endpoints. Explain, for a developer new to this codebase, what the resource is for and how its endpoints work together as a workflow.
|
|
62
|
-
|
|
63
|
-
Use the documented summaries where available. Where an endpoint has no documentation, infer cautiously from its HTTP method and path, and do not fabricate behavior.
|
|
64
|
-
|
|
65
|
-
FORMAT YOUR RESPONSE EXACTLY LIKE THIS:
|
|
66
|
-
|
|
67
|
-
## What this section does
|
|
68
|
-
1-2 sentences on the resource and its overall purpose.
|
|
69
|
-
|
|
70
|
-
## How the endpoints work together
|
|
71
|
-
A short narrative (2-4 sentences) describing the typical flow across these endpoints — e.g. how a client lists, creates, then updates this resource. Reference endpoints by their HTTP method and path.
|
|
72
|
-
|
|
73
|
-
## Notes
|
|
74
|
-
Up to 2 bullets on related models/services or anything a consumer must know. Omit this section if there is nothing concrete to say.
|
|
75
|
-
|
|
76
|
-
Do not invent endpoints, fields, or behavior not present in the graph. Keep the total response under 180 words.
|
|
77
|
-
|
|
78
|
-
---
|
|
79
|
-
|
|
80
|
-
Endpoint node ids in this section:
|
|
81
|
-
#{selected_node_ids.join("\n")}
|
|
82
|
-
|
|
83
|
-
Graph JSON:
|
|
84
|
-
#{JSON.pretty_generate(compact_graph)}
|
|
85
|
-
PROMPT
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
def compact_graph
|
|
89
|
-
nodes = selected_nodes
|
|
90
|
-
node_ids = nodes.map { |node| node[:id] }
|
|
91
|
-
|
|
92
|
-
# Include edges where at least one end is in the selection
|
|
93
|
-
related_edges = graph[:edges].select do |edge|
|
|
94
|
-
node_ids.include?(edge[:source]) || node_ids.include?(edge[:target])
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
# Also include neighbor nodes (one hop away) for context
|
|
98
|
-
neighbor_ids = Set.new(node_ids)
|
|
99
|
-
related_edges.each do |edge|
|
|
100
|
-
neighbor_ids.add(edge[:source])
|
|
101
|
-
neighbor_ids.add(edge[:target])
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
neighbor_nodes = graph[:nodes].select { |node| neighbor_ids.include?(node[:id]) }
|
|
105
|
-
|
|
106
|
-
{
|
|
107
|
-
selected_nodes: nodes.map { |node| compact_hash(node, %i[id type label status file metadata]) },
|
|
108
|
-
context_nodes: (neighbor_nodes - nodes).map { |node| compact_hash(node, %i[id type label status]) },
|
|
109
|
-
edges: related_edges.map { |edge| compact_hash(edge, %i[source target type confidence evidence]) },
|
|
110
|
-
stats: graph[:stats]
|
|
111
|
-
}
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
def selected_nodes
|
|
115
|
-
return graph[:nodes] if selected_node_ids.empty?
|
|
116
|
-
|
|
117
|
-
graph[:nodes].select { |node| selected_node_ids.include?(node[:id]) }
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
def compact_hash(hash, keys)
|
|
121
|
-
keys.each_with_object({}) do |key, result|
|
|
122
|
-
result[key] = hash[key] if hash.key?(key)
|
|
123
|
-
end
|
|
124
|
-
end
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
end
|