Skip to content

Commit 51123f9

Browse files
committed
Add C4 PlantUML architecture document derivation
1 parent 934c5b6 commit 51123f9

1 file changed

Lines changed: 85 additions & 17 deletions

File tree

ai-code-doc.el

Lines changed: 85 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@
2222

2323
(defconst ai-code--architecture-document-choices
2424
'(("Derive Architecture Guardrails" . ai-code-derive-architecture-guardrails)
25+
("Derive C4 PlantUML Architecture Document" . ai-code-derive-c4-plantuml)
2526
("Derive DDD Context for Repo" . ai-code-derive-ddd-context)
2627
("Derive Test Context Document" . ai-code-derive-test-context))
27-
"Choices for `ai-code-derive-architecture-document`.")
28+
"Choices for `ai-code-derive-architecture-document'.")
2829

2930
;;;###autoload
3031
(defun ai-code-derive-architecture-document ()
@@ -56,6 +57,10 @@ Default value is English."
5657
".ai.code.files/architecture/test-context.org"
5758
"Repository-relative path for the derived Test Context document.")
5859

60+
(defconst ai-code-c4-plantuml-output-relative-path
61+
".ai.code.files/architecture/c4-overview.org"
62+
"Repository-relative path for the derived C4 PlantUML architecture document.")
63+
5964
(defconst ai-code-file--architecture-guardrails-file-name
6065
"guardrails.org"
6166
"File name for derived architecture guardrails.")
@@ -85,6 +90,16 @@ Default value is English."
8590
"\n")
8691
"Initial Org template for architecture guardrails.")
8792

93+
(defun ai-code--ensure-architecture-document-file (file-name)
94+
"Ensure an architecture document named FILE-NAME exists and return its path."
95+
(let* ((files-dir (ai-code--ensure-files-directory))
96+
(architecture-dir (expand-file-name "architecture" files-dir))
97+
(target-file (expand-file-name file-name architecture-dir)))
98+
(make-directory architecture-dir t)
99+
(unless (file-exists-p target-file)
100+
(write-region "" nil target-file nil 'silent))
101+
target-file))
102+
88103
(defun ai-code--derive-ddd-context-prompt (git-root)
89104
"Build and return a formatted DDD context derivation prompt string for GIT-ROOT."
90105
(concat
@@ -131,6 +146,51 @@ Default value is English."
131146
"** Coverage Gaps & Actionable Testing Ideas\n"
132147
"** Notes and Uncertainties"))
133148

149+
(defun ai-code--derive-c4-plantuml-prompt (git-root)
150+
"Build and return a C4 PlantUML architecture document prompt for GIT-ROOT."
151+
(concat
152+
"Derive a C4-style architecture overview document for this existing repository.\n"
153+
"Generate the document as Org mode and embed PlantUML C4 diagrams in Org Babel source blocks.\n"
154+
"Create or update the document as an architecture reading guide, not just a collection of diagrams.\n"
155+
"Infer architecture from actual source files, tests, README files, package metadata, scripts, and configuration.\n"
156+
"Do not invent external systems, deployment topology, runtime dependencies, users, or protocols that are not supported by code or documentation.\n"
157+
"Mark uncertain boundaries, relationships, and naming choices explicitly.\n"
158+
"Prefer fewer boxes and clearer relationships over large, noisy diagrams.\n"
159+
"Use C4 only as an architectural draft for human review.\n"
160+
"When referencing any code file, folder, module, function, variable, or type, you MUST provide a relative Org-mode link in the format [[file:../../path/to/file::symbol_or_line][description_text]] pointing to its definition in the codebase (relative to the .ai.code.files/architecture/ output directory).\n"
161+
"For every diagram, include explanatory notes after the PlantUML block that summarize what the diagram shows and what remains uncertain.\n"
162+
"Use Org Babel blocks like #+begin_src plantuml :file c4-context.svg :exports both and include @startuml / @enduml inside each block.\n"
163+
"Use PlantUML C4 includes such as !include <C4/C4_Context>, !include <C4/C4_Container>, and !include <C4/C4_Component> when appropriate.\n"
164+
(format "Repository root: %s\n" git-root)
165+
(format "Create or update the Org file at %s.\n\n"
166+
ai-code-c4-plantuml-output-relative-path)
167+
"Use this Org structure:\n"
168+
"#+TITLE: C4 Architecture Overview\n\n"
169+
"* Purpose\n"
170+
"Explain what this generated architecture guide is for and what it does not prove.\n"
171+
"* Confidence and Assumptions\n"
172+
"List confidence level, source inputs, assumptions, and unverified areas.\n"
173+
"* Repository Summary\n"
174+
"Summarize the repository responsibilities in a few practical bullets.\n"
175+
"* Glossary\n"
176+
"Define terms used in the diagrams.\n"
177+
"* How to Read These Diagrams\n"
178+
"Explain the intended reading order: System Context, Container, Component, then runtime flows.\n"
179+
"* System Context\n"
180+
"Include a C4 System Context PlantUML Babel block and notes.\n"
181+
"* Container View\n"
182+
"Include a C4 Container PlantUML Babel block and notes. Treat containers as major deployable or logical units, not necessarily Docker containers.\n"
183+
"* Component View\n"
184+
"Include one focused C4 Component PlantUML Babel block for the most important container or module, and notes.\n"
185+
"* Important Runtime Flows\n"
186+
"Describe 1-3 important flows. Include a PlantUML sequence diagram when it helps.\n"
187+
"* Key Architectural Decisions\n"
188+
"List practical design choices inferred from the code and docs.\n"
189+
"* Open Questions\n"
190+
"List areas that need human confirmation.\n"
191+
"* Source Evidence\n"
192+
"Provide a table mapping important claims to Org links pointing at source evidence."))
193+
134194
(defun ai-code--architecture-guardrails-relative-path ()
135195
"Return the repo-relative path for the architecture guardrails file."
136196
(concat ai-code-files-dir-name "/"
@@ -207,17 +267,12 @@ Default value is English."
207267
;;;###autoload
208268
(defun ai-code-derive-ddd-context ()
209269
"Ask AI to derive a lightweight DDD context document for the current repo.
210-
The target Org file under `.ai.code.files/architecture/` is created if it does
270+
The target Org file under `.ai.code.files/architecture/' is created if it does
211271
not already exist, so the backend has a concrete document to create or update."
212272
(interactive)
213273
(let* ((git-root (or (ai-code--git-root)
214-
(user-error "Not inside a Git repository")))
215-
(files-dir (ai-code--ensure-files-directory))
216-
(architecture-dir (expand-file-name "architecture" files-dir))
217-
(target-file (expand-file-name "domain-context.org" architecture-dir)))
218-
(make-directory architecture-dir t)
219-
(unless (file-exists-p target-file)
220-
(write-region "" nil target-file nil 'silent))
274+
(user-error "Not inside a Git repository"))))
275+
(ai-code--ensure-architecture-document-file "domain-context.org")
221276
(let* ((base-prompt
222277
(concat (ai-code--derive-ddd-context-prompt git-root)
223278
(or (ai-code--format-repo-context-info) "")))
@@ -230,17 +285,12 @@ not already exist, so the backend has a concrete document to create or update."
230285
;;;###autoload
231286
(defun ai-code-derive-test-context ()
232287
"Ask AI to derive a lightweight Test Context document for the current repo.
233-
The target Org file under `.ai.code.files/architecture/` is created if it does
288+
The target Org file under `.ai.code.files/architecture/' is created if it does
234289
not already exist, so the backend has a concrete document to create or update."
235290
(interactive)
236291
(let* ((git-root (or (ai-code--git-root)
237-
(user-error "Not inside a Git repository")))
238-
(files-dir (ai-code--ensure-files-directory))
239-
(architecture-dir (expand-file-name "architecture" files-dir))
240-
(target-file (expand-file-name "test-context.org" architecture-dir)))
241-
(make-directory architecture-dir t)
242-
(unless (file-exists-p target-file)
243-
(write-region "" nil target-file nil 'silent))
292+
(user-error "Not inside a Git repository"))))
293+
(ai-code--ensure-architecture-document-file "test-context.org")
244294
(let* ((base-prompt
245295
(concat (ai-code--derive-test-context-prompt git-root)
246296
(or (ai-code--format-repo-context-info) "")))
@@ -250,5 +300,23 @@ not already exist, so the backend has a concrete document to create or update."
250300
(when final-prompt
251301
(ai-code--insert-prompt final-prompt)))))
252302

303+
;;;###autoload
304+
(defun ai-code-derive-c4-plantuml ()
305+
"Ask AI to derive a C4 PlantUML architecture document for the current repo.
306+
The target Org file under `.ai.code.files/architecture/' is created if it does
307+
not already exist, so the backend has a concrete document to create or update."
308+
(interactive)
309+
(let* ((git-root (or (ai-code--git-root)
310+
(user-error "Not inside a Git repository"))))
311+
(ai-code--ensure-architecture-document-file "c4-overview.org")
312+
(let* ((base-prompt
313+
(concat (ai-code--derive-c4-plantuml-prompt git-root)
314+
(or (ai-code--format-repo-context-info) "")))
315+
(initial-prompt (ai-code--append-document-language base-prompt))
316+
(final-prompt (ai-code-plain-read-string "Derive C4 PlantUML prompt: "
317+
initial-prompt)))
318+
(when final-prompt
319+
(ai-code--insert-prompt final-prompt)))))
320+
253321
(provide 'ai-code-doc)
254322
;;; ai-code-doc.el ends here

0 commit comments

Comments
 (0)