living-documentation 7.0.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 (173) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +329 -0
  3. package/dist/bin/cli.d.ts +3 -0
  4. package/dist/bin/cli.d.ts.map +1 -0
  5. package/dist/bin/cli.js +62 -0
  6. package/dist/bin/cli.js.map +1 -0
  7. package/dist/src/frontend/admin.html +1073 -0
  8. package/dist/src/frontend/annotations.js +546 -0
  9. package/dist/src/frontend/boot.js +90 -0
  10. package/dist/src/frontend/config.js +19 -0
  11. package/dist/src/frontend/dark-mode.js +20 -0
  12. package/dist/src/frontend/diagram/alignment.js +161 -0
  13. package/dist/src/frontend/diagram/clipboard.js +172 -0
  14. package/dist/src/frontend/diagram/constants.js +109 -0
  15. package/dist/src/frontend/diagram/debug.js +43 -0
  16. package/dist/src/frontend/diagram/edge-panel.js +260 -0
  17. package/dist/src/frontend/diagram/edge-rendering.js +12 -0
  18. package/dist/src/frontend/diagram/grid.js +78 -0
  19. package/dist/src/frontend/diagram/groups.js +102 -0
  20. package/dist/src/frontend/diagram/history.js +153 -0
  21. package/dist/src/frontend/diagram/image-name-modal.js +48 -0
  22. package/dist/src/frontend/diagram/image-upload.js +36 -0
  23. package/dist/src/frontend/diagram/label-editor.js +115 -0
  24. package/dist/src/frontend/diagram/link-panel.js +144 -0
  25. package/dist/src/frontend/diagram/main.js +299 -0
  26. package/dist/src/frontend/diagram/network.js +1473 -0
  27. package/dist/src/frontend/diagram/node-panel.js +267 -0
  28. package/dist/src/frontend/diagram/node-rendering.js +773 -0
  29. package/dist/src/frontend/diagram/persistence.js +161 -0
  30. package/dist/src/frontend/diagram/ports.js +386 -0
  31. package/dist/src/frontend/diagram/selection-overlay.js +336 -0
  32. package/dist/src/frontend/diagram/state.js +39 -0
  33. package/dist/src/frontend/diagram/t.js +3 -0
  34. package/dist/src/frontend/diagram/toast.js +21 -0
  35. package/dist/src/frontend/diagram/unlock-hold.js +182 -0
  36. package/dist/src/frontend/diagram/zoom.js +20 -0
  37. package/dist/src/frontend/diagram-link-modal.js +137 -0
  38. package/dist/src/frontend/diagram.html +1279 -0
  39. package/dist/src/frontend/documents.js +373 -0
  40. package/dist/src/frontend/export.js +338 -0
  41. package/dist/src/frontend/i18n/en.json +406 -0
  42. package/dist/src/frontend/i18n/fr.json +406 -0
  43. package/dist/src/frontend/i18n.js +32 -0
  44. package/dist/src/frontend/image-paste.js +101 -0
  45. package/dist/src/frontend/index.html +2314 -0
  46. package/dist/src/frontend/misc.js +25 -0
  47. package/dist/src/frontend/new-doc-modal.js +260 -0
  48. package/dist/src/frontend/new-folder-modal.js +174 -0
  49. package/dist/src/frontend/search.js +157 -0
  50. package/dist/src/frontend/sidebar-helpers.js +58 -0
  51. package/dist/src/frontend/sidebar.js +182 -0
  52. package/dist/src/frontend/snippet-detect.js +25 -0
  53. package/dist/src/frontend/snippet-table.js +85 -0
  54. package/dist/src/frontend/snippet-tree.js +94 -0
  55. package/dist/src/frontend/snippets.js +534 -0
  56. package/dist/src/frontend/state.js +28 -0
  57. package/dist/src/frontend/utils.js +21 -0
  58. package/dist/src/frontend/vendor/wordcloud2.js +1187 -0
  59. package/dist/src/frontend/wordcloud.js +693 -0
  60. package/dist/src/lib/config.d.ts +17 -0
  61. package/dist/src/lib/config.d.ts.map +1 -0
  62. package/dist/src/lib/config.js +79 -0
  63. package/dist/src/lib/config.js.map +1 -0
  64. package/dist/src/lib/parser.d.ts +11 -0
  65. package/dist/src/lib/parser.d.ts.map +1 -0
  66. package/dist/src/lib/parser.js +111 -0
  67. package/dist/src/lib/parser.js.map +1 -0
  68. package/dist/src/mcp/server.d.ts +3 -0
  69. package/dist/src/mcp/server.d.ts.map +1 -0
  70. package/dist/src/mcp/server.js +986 -0
  71. package/dist/src/mcp/server.js.map +1 -0
  72. package/dist/src/mcp/tools/diagrams.d.ts +44 -0
  73. package/dist/src/mcp/tools/diagrams.d.ts.map +1 -0
  74. package/dist/src/mcp/tools/diagrams.js +245 -0
  75. package/dist/src/mcp/tools/diagrams.js.map +1 -0
  76. package/dist/src/mcp/tools/documents.d.ts +26 -0
  77. package/dist/src/mcp/tools/documents.d.ts.map +1 -0
  78. package/dist/src/mcp/tools/documents.js +127 -0
  79. package/dist/src/mcp/tools/documents.js.map +1 -0
  80. package/dist/src/mcp/tools/source.d.ts +29 -0
  81. package/dist/src/mcp/tools/source.d.ts.map +1 -0
  82. package/dist/src/mcp/tools/source.js +200 -0
  83. package/dist/src/mcp/tools/source.js.map +1 -0
  84. package/dist/src/routes/annotations.d.ts +3 -0
  85. package/dist/src/routes/annotations.d.ts.map +1 -0
  86. package/dist/src/routes/annotations.js +83 -0
  87. package/dist/src/routes/annotations.js.map +1 -0
  88. package/dist/src/routes/browse.d.ts +3 -0
  89. package/dist/src/routes/browse.d.ts.map +1 -0
  90. package/dist/src/routes/browse.js +75 -0
  91. package/dist/src/routes/browse.js.map +1 -0
  92. package/dist/src/routes/config.d.ts +3 -0
  93. package/dist/src/routes/config.d.ts.map +1 -0
  94. package/dist/src/routes/config.js +97 -0
  95. package/dist/src/routes/config.js.map +1 -0
  96. package/dist/src/routes/diagrams.d.ts +3 -0
  97. package/dist/src/routes/diagrams.d.ts.map +1 -0
  98. package/dist/src/routes/diagrams.js +69 -0
  99. package/dist/src/routes/diagrams.js.map +1 -0
  100. package/dist/src/routes/documents.d.ts +8 -0
  101. package/dist/src/routes/documents.d.ts.map +1 -0
  102. package/dist/src/routes/documents.js +332 -0
  103. package/dist/src/routes/documents.js.map +1 -0
  104. package/dist/src/routes/export.d.ts +3 -0
  105. package/dist/src/routes/export.d.ts.map +1 -0
  106. package/dist/src/routes/export.js +277 -0
  107. package/dist/src/routes/export.js.map +1 -0
  108. package/dist/src/routes/images.d.ts +3 -0
  109. package/dist/src/routes/images.d.ts.map +1 -0
  110. package/dist/src/routes/images.js +49 -0
  111. package/dist/src/routes/images.js.map +1 -0
  112. package/dist/src/routes/wordcloud.d.ts +3 -0
  113. package/dist/src/routes/wordcloud.d.ts.map +1 -0
  114. package/dist/src/routes/wordcloud.js +95 -0
  115. package/dist/src/routes/wordcloud.js.map +1 -0
  116. package/dist/src/server.d.ts +7 -0
  117. package/dist/src/server.d.ts.map +1 -0
  118. package/dist/src/server.js +76 -0
  119. package/dist/src/server.js.map +1 -0
  120. package/dist/starting-doc/.annotations.json +3 -0
  121. package/dist/starting-doc/.diagrams.json +1884 -0
  122. package/dist/starting-doc/.living-doc.json +39 -0
  123. package/dist/starting-doc/1_tutorial/2026_04_11_13_25_[General]_crer_vos_dossiers.md +16 -0
  124. package/dist/starting-doc/1_tutorial/2026_04_11_18_58_[General]_creer_un_document_dans_un_dossier.md +9 -0
  125. package/dist/starting-doc/1_tutorial/2026_04_12_09_00_[General]_editer_et_sauvegarder.md +39 -0
  126. package/dist/starting-doc/1_tutorial/2026_04_12_10_00_[General]_utiliser_les_snippets.md +71 -0
  127. package/dist/starting-doc/2026_04_08_20_52_[General]_welcome.md +17 -0
  128. package/dist/starting-doc/2026_04_11_12_55_[General]_premiers_pas.md +271 -0
  129. package/dist/starting-doc/2_guide/2026_04_08_00_04_[DOCUMENT]_utilisation_des_images_plein_ecran_lien_clickable.md +40 -0
  130. package/dist/starting-doc/2_guide/2026_04_08_23_38_[Configuration]_demarrage_de_living_documentation.md +32 -0
  131. package/dist/starting-doc/2_guide/2026_04_09_09_00_[NAVIGATION]_recherche_plein_texte.md +65 -0
  132. package/dist/starting-doc/2_guide/2026_04_09_10_00_[EXPORT]_exporter_en_pdf.md +43 -0
  133. package/dist/starting-doc/2_guide/2026_04_09_11_00_[Configuration]_configurer_le_panneau_admin.md +55 -0
  134. package/dist/starting-doc/2_guide/2026_04_09_12_00_[Configuration]_extra_files.md +68 -0
  135. package/dist/starting-doc/2_guide/2026_04_09_13_00_[WORDCLOUD]_word_cloud.md +54 -0
  136. package/dist/starting-doc/2_guide/2026_04_09_14_00_[DIAGRAM]_creer_et_lier_un_diagramme.md +77 -0
  137. package/dist/starting-doc/3_concept/2026_04_08_20_58_[DOCUMENTING]_ADRS.md +20 -0
  138. package/dist/starting-doc/3_concept/2026_04_08_22_15_[DOCUMENTING]_living_documentation.md +17 -0
  139. package/dist/starting-doc/3_concept/2026_04_08_22_46_[METHODOLOGY]_diataxis_architecture_du_contenu.md +16 -0
  140. package/dist/starting-doc/4_reference/2026_04_08_23_14_[FUNDAMENTALS]_the_living_documentation_tool.md +41 -0
  141. package/dist/starting-doc/4_reference/2026_04_09_01_00_[REFERENCE]_raccourcis_clavier.md +61 -0
  142. package/dist/starting-doc/4_reference/2026_04_09_02_00_[REFERENCE]_tokens_pattern_nommage.md +75 -0
  143. package/dist/starting-doc/4_reference/2026_04_09_03_00_[REFERENCE]_types_de_snippets.md +68 -0
  144. package/dist/starting-doc/4_reference/2026_04_11_17_31_[FUNDAMENTALS]_architecturer_une_documentation.md +12 -0
  145. package/dist/starting-doc/4_reference/2026_04_12_14_07_[FUNDAMENTALS]_dossiers_et_catgories.md +89 -0
  146. package/dist/starting-doc/images/admin_screenshot.png +0 -0
  147. package/dist/starting-doc/images/ajout-document.png +0 -0
  148. package/dist/starting-doc/images/ajouter-document-categorie.png +0 -0
  149. package/dist/starting-doc/images/ajouter_un_document_dans_un_dossier.png +0 -0
  150. package/dist/starting-doc/images/architecturer_une_documentation_reference.png +0 -0
  151. package/dist/starting-doc/images/cr_er_un_document.png +0 -0
  152. package/dist/starting-doc/images/creation-nouveau-dossier.png +0 -0
  153. package/dist/starting-doc/images/creer-document-context-engineering.png +0 -0
  154. package/dist/starting-doc/images/creer-dossier-only-tutoriel.png +0 -0
  155. package/dist/starting-doc/images/creer-dossier-tutoriel.png +0 -0
  156. package/dist/starting-doc/images/creer-dossiers-done.png +0 -0
  157. package/dist/starting-doc/images/creer-un-document.png +0 -0
  158. package/dist/starting-doc/images/creer-vos-dossiers-tutoriel.png +0 -0
  159. package/dist/starting-doc/images/creer-vos-dossiers.png +0 -0
  160. package/dist/starting-doc/images/decouverte_adrs.png +0 -0
  161. package/dist/starting-doc/images/diataxis.png +0 -0
  162. package/dist/starting-doc/images/diataxis_callout.png +0 -0
  163. package/dist/starting-doc/images/document-cree.png +0 -0
  164. package/dist/starting-doc/images/liens_snippets.png +0 -0
  165. package/dist/starting-doc/images/living_documentation.png +0 -0
  166. package/dist/starting-doc/images/npm_logo.png +0 -0
  167. package/dist/starting-doc/images/popup-creer-document.png +0 -0
  168. package/dist/starting-doc/images/popup-creer-dossier.png +0 -0
  169. package/dist/starting-doc/images/popup-dossier-cree.png +0 -0
  170. package/dist/starting-doc/images/quatre-dossiers-crees.png +0 -0
  171. package/dist/starting-doc/images/screenshot-living-doc.png +0 -0
  172. package/dist/starting-doc/images/the_living_documentation_tool.png +0 -0
  173. package/package.json +49 -0
@@ -0,0 +1,986 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mcpRouter = mcpRouter;
4
+ const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
5
+ const streamableHttp_js_1 = require("@modelcontextprotocol/sdk/server/streamableHttp.js");
6
+ const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
7
+ const express_1 = require("express");
8
+ const documents_1 = require("./tools/documents");
9
+ const diagrams_1 = require("./tools/diagrams");
10
+ const source_1 = require("./tools/source");
11
+ // ── Server guide ──────────────────────────────────────────────────────────────
12
+ // Shared by the `instructions` field (sent on MCP initialize) and the
13
+ // `get_server_guide` tool (explicit retrieval for clients that don't surface
14
+ // server instructions to the model).
15
+ const SERVER_GUIDE = `# Living Documentation — Server Guide
16
+
17
+ This server maintains a living documentation system composed of:
18
+ - **Documents** (Markdown) — the source of truth.
19
+ - **Diagrams** — visual derivations of documents.
20
+
21
+ ## Document ↔ diagram contract
22
+ Documents are authoritative. Diagrams are derived views and must not introduce
23
+ information that is absent from the documents. If a diagram needs a concept
24
+ that isn't documented yet, create or update the document first.
25
+
26
+ ## Default diagram scope
27
+ - When documenting the project big picture, generate a **context diagram**.
28
+ - Do NOT generate container diagrams, component diagrams, or UML diagrams
29
+ unless the user explicitly asks for them by name.
30
+ - If the user asks for "a diagram", "the big picture", or "documentation",
31
+ produce a context diagram.
32
+
33
+ ## Mandatory workflow before creating or updating any diagram
34
+ 1. Call \`list_documents\` to see what exists.
35
+ 2. Call \`read_document\` on the documents relevant to the requested diagram.
36
+ 3. Call \`list_diagrams\` to check whether the diagram already exists
37
+ (update rather than duplicate by passing its \`id\` back to \`create_diagram\`).
38
+ 4. Only then call \`create_diagram\`, using node/edge content grounded in the
39
+ documents you read.
40
+
41
+ Never invent actors, systems, or relationships that are not present in the
42
+ documents.
43
+
44
+ ## Conventions by diagram type
45
+ ### Context diagram (default)
46
+ - Central system as \`box\` (c-blue).
47
+ - Users / roles as \`actor\` (c-gray).
48
+ - External systems as \`box\` (c-slate).
49
+ - Persistence / datastores as \`database\` (c-teal).
50
+ - Keep to ~10 nodes maximum.
51
+
52
+ ### Container diagram (explicit request only)
53
+ - Each deployable unit as \`box\`.
54
+ - Databases as \`database\`.
55
+ - Queues as \`ellipse\`.
56
+
57
+ ### UML diagram (explicit request only)
58
+ - Follow the requested UML variant's conventions (class, sequence, state,
59
+ activity, use-case …).
60
+
61
+ ### Screen-guide diagram (explicit request only)
62
+ An annotated screenshot built in **three layers**. Source code is the reference
63
+ (not the Markdown docs) — use \`read_source_file\` / \`search_source\`.
64
+
65
+ **1. Background image** — one \`image\` node with the screenshot.
66
+ - \`name: "screenshot"\` (used as edge anchor; not displayed).
67
+ - \`imageSrc\`: URL returned by \`POST /api/images/upload\`.
68
+ - \`width\` / \`height\` = natural screenshot pixels. \`locked: true\`.
69
+
70
+ **2. Zone overlays** — one translucent \`box\` per major layout region
71
+ (left/right sidebar, top bar, main content, footer …).
72
+ - \`bgOpacity: 0.15–0.20\`, \`locked: true\`, empty label.
73
+ - \`width\` / \`height\` / \`x\` / \`y\` cover the zone on the screenshot.
74
+ - One distinct \`color\` per zone (e.g. c-red = left drawer, c-amber = top bar,
75
+ c-cyan = main area). Typical count: **2–5 zones**.
76
+ - Each zone gets a **zone-label post-it** of the **same color**, placed inside
77
+ or at the edge of the zone (1–3 words: "Top Bar", "Collapsible Drawer",
78
+ "Main Page").
79
+
80
+ **3. Feature callouts** — one \`post-it\` per first-level feature, placed
81
+ **outside the screenshot** and linked to the UI element by a free-end arrow.
82
+ - First-level feature = visible without interaction + changes behavior
83
+ significantly when used. Typical count: **4–10**.
84
+ - Label: 2–5 words, title-cased; multi-line allowed via \`\\n\`.
85
+ - Color depends on kind:
86
+ - **Interactive** (button, link, input, toggle) → \`c-amber\` or
87
+ \`c-orange\` (yellow family). **Default.**
88
+ - **Differentiating** (product-distinguishing feature) → a distinct
89
+ non-yellow color (\`c-purple\`, \`c-rose\`, \`c-red\`, \`c-sky\`,
90
+ \`c-teal\`, \`c-green\`). Reserve for the 1–3 hero features.
91
+
92
+ #### Free-end arrows — never anchor on the image node
93
+ Anchoring on the image makes every arrow converge to its centre. Use one of:
94
+ - **\`anchor\` node** (8×8, invisible at rest, visible on hover) placed on the
95
+ target pixel inside the screenshot, with edge
96
+ \`{ from: "<post-it>", to: "<anchor name>" }\`. **Preferred.**
97
+ - **Edge with \`from\` only (no \`to\`)** — renders a floating arrow
98
+ endpoint the user can drag onto the target.
99
+
100
+ Edge labels stay empty on this diagram type — the arrow alone speaks. Missing-
101
+ label warnings are disabled for screen-guide.
102
+
103
+ ### Edges
104
+ - Every edge MUST have a \`label\` describing the interaction as a verb phrase
105
+ ("authenticates", "publishes events to", "reads from", "sends notifications via").
106
+ - Exception: screen-guide diagrams may have unlabeled edges.
107
+
108
+ ## Node label format (C4 convention)
109
+ Use \`\\n\` line breaks:
110
+ \`\`\`
111
+ Name\\n[Type]\\nShort description of role or responsibility
112
+ \`\`\`
113
+ Types: \`[Person]\`, \`[Software System]\`, \`[External System]\`, \`[Database]\`, \`[Device]\`.
114
+ Keep descriptions to 1–2 short lines.
115
+
116
+ ## Coordinate system (when positions are provided)
117
+ - Origin \`(0, 0)\` is the canvas center.
118
+ - \`+x\` is right, \`+y\` is down.
119
+ - Use multiples of **40** for grid alignment.
120
+ - \`x\` and \`y\` are **optional**: omit them to let the editor auto-lay out
121
+ nodes. Only provide coordinates when you want a fixed layout (e.g., following
122
+ a C4 convention).
123
+ - **Screen-guide exception**: positions align to screenshot pixels (and
124
+ anchors to target pixels), not to the 40-unit grid.
125
+
126
+ ## Source code access (fallback only)
127
+ Three tools expose read-only access to the project source under \`sourceRoot\`
128
+ (configurable in \`.living-doc.json\`; defaults to the parent folder of
129
+ \`docsFolder\`):
130
+
131
+ - \`list_source_files(pattern?, maxResults?)\`
132
+ - \`read_source_file(path)\`
133
+ - \`search_source(query, pattern?, maxResults?, caseSensitive?)\`
134
+
135
+ **Rules**:
136
+ 1. Documentation tools come first. Use source tools only when the docs do not
137
+ carry the required detail (typical case: screen-guide diagrams, or
138
+ low-level code documentation with no ADR).
139
+ 2. If you find yourself reading more than 3 source files for the same
140
+ diagram, stop and update the documentation first.
141
+ 3. Common ignored folders (\`node_modules\`, \`dist\`, \`.git\`, \`build\`,
142
+ \`target\`, …) are skipped automatically.
143
+
144
+ ## Guardrails (enforced server-side in create_diagram)
145
+ - \`diagramType\` is required.
146
+ - Non-context types (\`container\`, \`component\`, \`uml\`, \`screen-guide\`) are
147
+ rejected unless \`userRequestedExplicitly: true\` is also passed.
148
+ - \`image\` nodes without \`imageSrc\` are rejected.
149
+ - A response \`warnings\` array flags missing edge labels (except for
150
+ screen-guide) or oversized context diagrams.
151
+ `;
152
+ // ── Tool definitions ──────────────────────────────────────────────────────────
153
+ const SHAPE_LIST = 'box, actor (person), database, ellipse, circle, post-it, text-free, image, anchor (invisible endpoint for free-end arrows — screen-guide only)';
154
+ const COLOR_LIST = 'c-blue, c-green, c-gray, c-teal, c-amber, c-orange, c-rose, c-purple, c-cyan, c-indigo, c-pink, c-lime, c-red, c-sky, c-slate (short aliases like "blue", "teal" also work)';
155
+ const GUIDE_HINT = 'If unsure of the workflow, call `get_server_guide` first.';
156
+ const CREATE_DIAGRAM_DESCRIPTION = [
157
+ 'Create or overwrite a diagram from a high-level description.',
158
+ '',
159
+ '## Required workflow (do ALL of these before calling)',
160
+ '1. `list_documents` — see what exists.',
161
+ '2. `read_document` on documents relevant to the diagram.',
162
+ '3. `list_diagrams` — if the diagram already exists, pass its `id` back to update in place (do not duplicate).',
163
+ 'Do not invent actors, systems, or relationships absent from the documents.',
164
+ '',
165
+ '## Scope rule',
166
+ 'The default diagram for a project is a **context diagram**. Container, component, and UML diagrams are produced ONLY when the user explicitly requests them by name. If the user asks for "a diagram", "the big picture", or "documentation", produce a context diagram.',
167
+ '',
168
+ '## Conventions by diagram type',
169
+ '- Context (default): central system as `box` (c-blue); users as `actor` (c-gray); external systems as `box` (c-slate); datastores as `database` (c-teal). Max ~10 nodes.',
170
+ '- Container (explicit-only): deployables as `box`, databases as `database`, queues as `ellipse`.',
171
+ '- UML (explicit-only): follow the requested UML variant (class, sequence, state, …).',
172
+ '- Every edge MUST have a `label` describing the interaction as a verb phrase ("authenticates", "publishes events to", "reads from").',
173
+ '',
174
+ '## Source-of-truth contract',
175
+ 'Documents are authoritative. A diagram must not contain information absent from the documents. If a diagram needs a concept that isn\'t documented, create or update the document first (via `create_document`).',
176
+ '',
177
+ '## Positioning',
178
+ '`x` and `y` are **optional**. Omit them and the editor auto-lays out nodes. Provide coordinates only when a fixed layout is required (e.g., following a C4 convention). When provided: origin `(0,0)` is the canvas center, `+x` = right, `+y` = down; use multiples of 40.',
179
+ '',
180
+ '## Guardrails (enforced)',
181
+ '- `diagramType` is required.',
182
+ '- For `container`, `component`, or `uml`, `userRequestedExplicitly: true` is required — confirms the user asked for that type by name. Otherwise the call is rejected.',
183
+ '- Missing edge labels and oversized context diagrams produce warnings.',
184
+ '',
185
+ '## Worked example (context diagram, derived from an ADR)',
186
+ '```json',
187
+ '{',
188
+ ' "diagramType": "context",',
189
+ ' "title": "Living Documentation — system context",',
190
+ ' "nodes": [',
191
+ ' { "name": "Living Documentation\\n[Software System]\\nServes Markdown docs\\nand diagrams", "type": "box", "color": "c-blue" },',
192
+ ' { "name": "Developer\\n[Person]\\nBrowses and edits\\nproject docs", "type": "actor", "color": "c-gray" },',
193
+ ' { "name": "Local filesystem\\n[Datastore]\\nHosts .md files and\\ndiagrams.json", "type": "database","color": "c-teal" }',
194
+ ' ],',
195
+ ' "edges": [',
196
+ ' { "from": "Developer\\n[Person]\\nBrowses and edits\\nproject docs", "to": "Living Documentation\\n[Software System]\\nServes Markdown docs\\nand diagrams", "label": "reads and edits docs via" },',
197
+ ' { "from": "Living Documentation\\n[Software System]\\nServes Markdown docs\\nand diagrams", "to": "Local filesystem\\n[Datastore]\\nHosts .md files and\\ndiagrams.json", "label": "reads from / writes to" }',
198
+ ' ]',
199
+ '}',
200
+ '```',
201
+ '',
202
+ `## Available shapes and colors`,
203
+ `Shapes: ${SHAPE_LIST}.`,
204
+ `Colors: ${COLOR_LIST}.`,
205
+ '',
206
+ GUIDE_HINT,
207
+ ].join('\n');
208
+ const CREATE_DOCUMENT_DESCRIPTION = [
209
+ 'Create a new Markdown document. The filename is generated automatically from the configured pattern (date + category + title slug). Pass `content` as full Markdown; omit to create an empty stub.',
210
+ '',
211
+ '## Source-of-truth contract',
212
+ 'Documents are the source of truth. Diagrams are derived views. If a diagram needs a concept that isn\'t documented, create or update the document first (here) before calling `create_diagram`.',
213
+ '',
214
+ '## Worked example',
215
+ '```json',
216
+ '{',
217
+ ' "title": "Payment system context",',
218
+ ' "category": "Architecture",',
219
+ ' "folder": "adrs",',
220
+ ' "content": "# Payment system context\\n\\n**status:** Accepted\\n**tags:** context, payment\\n\\nThe system integrates with Stripe for card capture and pre-authorization..."',
221
+ '}',
222
+ '```',
223
+ '',
224
+ GUIDE_HINT,
225
+ ].join('\n');
226
+ const TOOLS = [
227
+ {
228
+ name: 'get_server_guide',
229
+ description: 'Return the living-documentation server guide: purpose, mandatory workflow, scope rules (context vs container/UML), diagram conventions, node/edge format, and coordinate system. Call this first whenever you are unsure how to use the server.',
230
+ inputSchema: { type: 'object', properties: {} },
231
+ },
232
+ {
233
+ name: 'list_documents',
234
+ description: `List all documents with their id, title, category, and folder. Documents are the source of truth — read them before creating or updating any diagram. ${GUIDE_HINT}`,
235
+ inputSchema: { type: 'object', properties: {} },
236
+ },
237
+ {
238
+ name: 'read_document',
239
+ description: `Read the raw Markdown content of a document by its id. Use this to gather facts (actors, systems, flows) before creating a diagram. Ignore documents whose frontmatter contains \`status: SuperSeeded\`. ${GUIDE_HINT}`,
240
+ inputSchema: {
241
+ type: 'object',
242
+ properties: {
243
+ id: { type: 'string', description: 'Document id as returned by list_documents' },
244
+ },
245
+ required: ['id'],
246
+ },
247
+ },
248
+ {
249
+ name: 'create_document',
250
+ description: CREATE_DOCUMENT_DESCRIPTION,
251
+ inputSchema: {
252
+ type: 'object',
253
+ properties: {
254
+ title: { type: 'string', description: 'Human-readable document title' },
255
+ category: { type: 'string', description: 'Category extracted from the filename, e.g. "Architecture", "Guide"' },
256
+ folder: { type: 'string', description: 'Optional subfolder relative to the docs root, e.g. "adrs" or "adrs/backend"' },
257
+ content: { type: 'string', description: 'Full Markdown content. Omit to create an empty document.' },
258
+ },
259
+ required: ['title', 'category'],
260
+ },
261
+ },
262
+ {
263
+ name: 'list_diagrams',
264
+ description: `List all saved diagrams with their id and title. Always call this before \`create_diagram\` — if a relevant diagram already exists, pass its id back to \`create_diagram\` to update rather than duplicate. ${GUIDE_HINT}`,
265
+ inputSchema: { type: 'object', properties: {} },
266
+ },
267
+ {
268
+ name: 'read_diagram',
269
+ description: `Read the nodes and edges of an existing diagram by its id. Returns the diagram in the same format accepted by \`create_diagram\`, ready to be modified and passed back. ${GUIDE_HINT}`,
270
+ inputSchema: {
271
+ type: 'object',
272
+ properties: {
273
+ id: { type: 'string', description: 'Diagram id as returned by list_diagrams' },
274
+ },
275
+ required: ['id'],
276
+ },
277
+ },
278
+ {
279
+ name: 'create_diagram',
280
+ description: CREATE_DIAGRAM_DESCRIPTION,
281
+ inputSchema: {
282
+ type: 'object',
283
+ properties: {
284
+ id: { type: 'string', description: 'Optional: existing diagram id to overwrite. If omitted, a new diagram is created.' },
285
+ title: { type: 'string', description: 'Diagram title' },
286
+ diagramType: {
287
+ type: 'string',
288
+ enum: ['context', 'container', 'component', 'uml', 'flow', 'erd', 'screen-guide', 'other'],
289
+ description: 'Type of diagram. "context" is the default. "container", "component", "uml", and "screen-guide" require explicit user request — set `userRequestedExplicitly: true` alongside them.',
290
+ },
291
+ userRequestedExplicitly: {
292
+ type: 'boolean',
293
+ description: 'Set to true only when the user explicitly asked for a container, component, UML, or screen-guide diagram by name. Required for those diagramType values; ignored for "context".',
294
+ },
295
+ nodes: {
296
+ type: 'array',
297
+ description: 'List of nodes. Node labels should follow the C4 convention: "Name\\n[Type]\\nShort description".',
298
+ items: {
299
+ type: 'object',
300
+ properties: {
301
+ name: { type: 'string', description: 'Node label shown in the diagram. Use \\n for line breaks. C4 format: "Name\\n[Type]\\nDescription". Empty string allowed for zone overlays, anchors, and the image background.' },
302
+ type: { type: 'string', description: `Shape type: ${SHAPE_LIST}.` },
303
+ color: { type: 'string', description: `Color key, e.g. c-blue or "blue". Available: ${COLOR_LIST}.` },
304
+ x: { type: 'number', description: 'Optional canvas X (0 = center). Omit to auto-lay out. When provided, use multiples of 40 (screen-guide exception: pixel-aligned).' },
305
+ y: { type: 'number', description: 'Optional canvas Y (0 = center, positive = down). Omit to auto-lay out. When provided, use multiples of 40 (screen-guide exception: pixel-aligned).' },
306
+ width: { type: 'number', description: 'Optional explicit node width in pixels. Required for image backgrounds and zone overlays in screen-guide diagrams. Otherwise estimated from the label.' },
307
+ height: { type: 'number', description: 'Optional explicit node height in pixels. Required for image backgrounds and zone overlays in screen-guide diagrams. Otherwise estimated from the label.' },
308
+ bgOpacity: { type: 'number', description: 'Optional background opacity (0–1). Use 0.15–0.20 for translucent zone-overlay boxes in screen-guide diagrams.' },
309
+ locked: { type: 'boolean', description: 'Optional: lock the node so it cannot be moved or resized by accident. Recommended for screen-guide backgrounds and zone overlays.' },
310
+ linkedDiagramId: { type: 'string', description: 'Optional: id of another diagram to navigate to when clicking this node (C4 drill-down).' },
311
+ imageSrc: { type: 'string', description: 'Required when `type` is "image". URL path returned by POST /api/images/upload (e.g. "/images/foo.png").' },
312
+ },
313
+ required: ['name', 'type'],
314
+ },
315
+ },
316
+ edges: {
317
+ type: 'array',
318
+ description: 'List of directed edges between nodes. Every edge should have a `label` describing the interaction (verb phrase). Exception: screen-guide edges have empty labels.',
319
+ items: {
320
+ type: 'object',
321
+ properties: {
322
+ from: { type: 'string', description: 'Name of the source node (must match a node `name` exactly).' },
323
+ to: { type: 'string', description: 'Name of the target node (must match a node `name` exactly). Optional for screen-guide diagrams — omit to render a free-end arrow the user can drag.' },
324
+ label: { type: 'string', description: 'Edge label — verb phrase describing the interaction. Strongly recommended; missing labels produce warnings (except for screen-guide).' },
325
+ },
326
+ required: ['from'],
327
+ },
328
+ },
329
+ },
330
+ required: ['title', 'diagramType', 'nodes', 'edges'],
331
+ },
332
+ },
333
+ {
334
+ name: 'list_source_files',
335
+ description: [
336
+ 'List files under the project `sourceRoot` (configured in `.living-doc.json`, defaults to the parent folder of the docs directory).',
337
+ '',
338
+ 'Use this tool as a **fallback** when the Markdown documentation lacks a specific low-level detail needed for a diagram — for example, when generating a screen-guide diagram or when documenting a piece of code that has no ADR. For architectural facts, read documents first.',
339
+ '',
340
+ 'Common ignored folders are skipped automatically (`node_modules`, `dist`, `.git`, `build`, `target`, etc.).',
341
+ ].join('\n'),
342
+ inputSchema: {
343
+ type: 'object',
344
+ properties: {
345
+ pattern: { type: 'string', description: 'Optional glob-like pattern matched against the relative path. Supports `*` (within a segment) and `**` (across segments). Example: `src/**/*.ts`.' },
346
+ maxResults: { type: 'number', description: 'Max number of files to return (default 500, hard cap 2000).' },
347
+ },
348
+ },
349
+ },
350
+ {
351
+ name: 'read_source_file',
352
+ description: [
353
+ 'Read a source file under the project `sourceRoot`. Path must be relative to `sourceRoot`.',
354
+ '',
355
+ 'Use this **only after** you have tried the documentation tools (`list_documents` / `read_document`). If you find yourself reading more than 3 source files for the same diagram, stop and update the documentation first — the docs are the source of truth.',
356
+ '',
357
+ 'Files larger than 512 KB are rejected; use `search_source` to locate the relevant section.',
358
+ ].join('\n'),
359
+ inputSchema: {
360
+ type: 'object',
361
+ properties: {
362
+ path: { type: 'string', description: 'Path relative to `sourceRoot`, e.g. `src/frontend/index.html`.' },
363
+ },
364
+ required: ['path'],
365
+ },
366
+ },
367
+ {
368
+ name: 'search_source',
369
+ description: [
370
+ 'Grep-like text search across files under the project `sourceRoot`.',
371
+ '',
372
+ 'Preferred over `read_source_file` when you only need to locate a symbol, identifier, or string. Returns `{ file, line, text }` matches.',
373
+ ].join('\n'),
374
+ inputSchema: {
375
+ type: 'object',
376
+ properties: {
377
+ query: { type: 'string', description: 'Substring to match (plain text, not regex).' },
378
+ pattern: { type: 'string', description: 'Optional glob to restrict the search (e.g. `src/**/*.ts`).' },
379
+ caseSensitive: { type: 'boolean', description: 'Default false.' },
380
+ maxResults: { type: 'number', description: 'Max number of matches to return (default 200, hard cap 1000).' },
381
+ },
382
+ required: ['query'],
383
+ },
384
+ },
385
+ ];
386
+ // ── MCP Prompts ────────────────────────────────────────────────────────────────
387
+ // Prompt templates guide the LLM to produce well-structured create_diagram
388
+ // calls. Layout work (positions, types, colors) happens on the caller's side —
389
+ // zero tokens consumed by the server.
390
+ const PROMPTS = [
391
+ {
392
+ name: 'generate-context-diagram',
393
+ description: 'DEFAULT. Generate a C4 System Context diagram — one system in the center, surrounding users and external systems. Safe to auto-invoke when the user asks for "a diagram", "the big picture", or "documentation".',
394
+ arguments: [
395
+ { name: 'scope', description: 'Optional: name of the system to put at the center. Inferred from the docs if omitted.', required: false },
396
+ ],
397
+ },
398
+ {
399
+ name: 'generate-container-diagram',
400
+ description: 'EXPLICIT-ONLY. Generate a C4 Container diagram (internal containers of a single system). Invoke this only when the user explicitly asks for a "container diagram".',
401
+ },
402
+ {
403
+ name: 'generate-uml-diagram',
404
+ description: 'EXPLICIT-ONLY. Generate a UML diagram. Invoke this only when the user explicitly asks for a "UML diagram" by name.',
405
+ arguments: [
406
+ { name: 'umlType', description: 'UML variant: class, sequence, state, activity, or use-case.', required: true },
407
+ ],
408
+ },
409
+ {
410
+ name: 'update-diagram-from-docs',
411
+ description: 'Re-read source documents and update existing diagrams so they reflect the current state of the documentation. Accepts an optional diagramId to target a single diagram.',
412
+ arguments: [
413
+ { name: 'diagramId', description: 'Optional: id of a single diagram to update. If omitted, all diagrams are inspected.', required: false },
414
+ ],
415
+ },
416
+ {
417
+ name: 'generate-screen-guide',
418
+ description: 'EXPLICIT-ONLY. Generate an annotated UI guide: a screenshot image as the background with post-it notes describing each UI element. Reads the source code of the screen (HTML/JSX/template). Invoke only when the user explicitly asks for a "screen guide", "UI guide", or "annotated screenshot".',
419
+ arguments: [
420
+ { name: 'screenFile', description: 'Relative path (under sourceRoot) of the screen source file to document, e.g. `src/frontend/index.html`.', required: true },
421
+ { name: 'screenshotUrl', description: 'Optional: URL of the uploaded screenshot (e.g. `/images/index-2026.png`). If omitted, the prompt will instruct the user to upload one via the Admin UI first.', required: false },
422
+ ],
423
+ },
424
+ {
425
+ name: 'flow',
426
+ description: 'Left-to-right linear flow diagram — steps or stages in a process.',
427
+ },
428
+ {
429
+ name: 'erd',
430
+ description: 'Entity-Relationship Diagram — entities as boxes, relationships as labeled edges.',
431
+ },
432
+ ];
433
+ // Prepended to every diagram prompt — enforces ADR-first information gathering.
434
+ const PREAMBLE = `
435
+ ## Before anything else — mine the existing documentation
436
+
437
+ Living Documentation is a tool where knowledge lives primarily in Markdown documents (ADRs, guides, decisions).
438
+ **Do not ask the user questions you can answer yourself by reading the docs.**
439
+
440
+ 1. Call \`list_documents\` to get the full document list.
441
+ 2. Read documents that look architecturally significant regardless of their folder name — look for ADR-style frontmatter (lines starting with \`**status:**\`, \`**description:**\`, \`**tags:**\`), README files, and any document whose title or category suggests architecture, integration, or domain knowledge.
442
+ 3. **Ignore any document whose frontmatter contains \`status: SuperSeeded\`** — it is deprecated and must not be used as a source of truth.
443
+ 4. Read the frontmatter (\`description\` and \`tags\` fields) of each relevant document with \`read_document\` to find answers to the diagram-specific questions below.
444
+ 5. Only ask the user for information that cannot be found in any active (non-superseded) document.
445
+
446
+ ## Node label format — mandatory
447
+
448
+ Every node label must follow the Simon Brown C4 convention using \\n for line breaks:
449
+
450
+ \`\`\`
451
+ Name\\n[Type]\\nShort description of role or responsibility
452
+ \`\`\`
453
+
454
+ Examples:
455
+ - \`"DriveBox\\n[Software System]\\nManages ad campaigns\\ndisplayed on taxi tablets"\`
456
+ - \`"Advertiser\\n[Person]\\nUploads media and\\npays for campaigns"\`
457
+ - \`"Stripe\\n[External System]\\nCard payment and\\npre-authorization"\`
458
+
459
+ Types to use: \`[Person]\`, \`[Software System]\`, \`[External System]\`, \`[Database]\`, \`[Device]\`
460
+ Keep descriptions short — 1 to 2 lines maximum.
461
+
462
+ ## C4 progression — mandatory ordering
463
+
464
+ C4 diagrams must be created in strict order:
465
+
466
+ 1. **Context first** — the entry point when scanning a project's docs for the first time.
467
+ It answers: what is the system, who uses it, what external systems does it integrate with?
468
+ 2. **Container after** — a drill-down created only when a Context diagram already exists
469
+ **and** the reader explicitly asks to go deeper into a specific system.
470
+ 3. **Component after that** — same rule, only after a Container exists.
471
+
472
+ **When reading docs for the first time, always create the Context diagram.**
473
+ Never jump to Container or Component as the first diagram for a system.
474
+
475
+ ## Linked diagrams — C4 drill-down
476
+
477
+ Any node can link to an **already-existing** diagram for navigation (e.g. Context → Container → Component).
478
+
479
+ **Workflow:**
480
+ 1. Call \`list_diagrams\`.
481
+ 2. If a relevant child diagram already exists, add \`linkedDiagramId: "<id>"\` on the matching node.
482
+ 3. If no child diagram exists, leave \`linkedDiagramId\` unset.
483
+
484
+ **RULE — never create child diagrams automatically.**
485
+ Container and Component diagrams are only created on explicit user request for a specific scope.
486
+ Do not create them as a side effect of creating a Context diagram.
487
+
488
+ Clicking a linked node in the editor navigates directly to the child diagram.
489
+ `.trim();
490
+ function buildPromptTemplate(name, args) {
491
+ switch (name) {
492
+ case 'generate-context-diagram':
493
+ return `
494
+ ${PREAMBLE}
495
+
496
+ ---
497
+
498
+ You are about to create a **C4 System Context Diagram** following Simon Brown's C4 model.
499
+
500
+ ## Step 1 — Answer these three questions first (ask the user only if not found in docs)
501
+
502
+ 1. **Scope** — What is the software system we are describing?${args.scope ? ` (The user specified: **${args.scope}**.)` : ' What is its name and primary responsibility?'}
503
+ 2. **Users** — Who uses it? For each type of user: what are they doing with the system?
504
+ 3. **Integrations** — What external systems does it need to integrate with? What data or interactions flow between them?
505
+
506
+ Do not proceed to the diagram until you have clear answers to all three.
507
+
508
+ ## Step 2 — Build the diagram
509
+
510
+ ### Layout rules (grid = 40 units, physics is disabled — positions are final)
511
+ - **Main system** → center: x: 0, y: 0. Type: box. Color: c-blue.
512
+ - **Human users (actors)** → left: x: -320, y: 0. Spread vertically by ±160 if several. Type: actor. Color: c-gray.
513
+ - **External systems** → right: x: 320, y: 0. Spread vertically by ±160 if several. Type: box. Color: c-slate.
514
+ - **External databases / datastores** → below: x: 0, y: 240. Type: database. Color: c-teal.
515
+ - All positions must be multiples of 40.
516
+ - Keep the diagram under ~10 nodes total.
517
+
518
+ ### Edge rules
519
+ - Direction: actor → system, system → external system, system → datastore.
520
+ - Every edge must have a label describing the interaction in plain language (e.g. "submits orders", "reads customer data", "sends notifications via").
521
+
522
+ ### Color palette
523
+ | Element | Color |
524
+ |---|---|
525
+ | Main system | c-blue |
526
+ | Human actor | c-gray |
527
+ | External system | c-slate |
528
+ | Datastore | c-teal |
529
+
530
+ ## Step 3 — Call \`create_diagram\` with \`diagramType: "context"\`.
531
+ `.trim();
532
+ case 'generate-container-diagram':
533
+ return `
534
+ ${PREAMBLE}
535
+
536
+ ---
537
+
538
+ You are about to create a **C4 Container Diagram** following Simon Brown's C4 model.
539
+
540
+ ## ⚠️ Explicit-request check
541
+ Only proceed if the user explicitly asked for a *container* diagram. If the request was generic ("a diagram", "the big picture"), stop and use \`generate-context-diagram\` instead.
542
+
543
+ ## ⚠️ Pre-flight check — mandatory before anything else
544
+
545
+ 1. Call \`list_diagrams\`.
546
+ 2. If **no C4 Context diagram exists** for the target system → **stop here**.
547
+ - Inform the user that a Context diagram must be created first.
548
+ - Create the Context diagram using the \`generate-context-diagram\` prompt rules.
549
+ - Do not create the Container diagram in this session.
550
+ 3. Only proceed to the Container diagram if a Context diagram already exists.
551
+
552
+ ## Step 1 — Answer these questions first (ask the user only if not found in docs)
553
+
554
+ 1. **System** — Which system are we zooming into?
555
+ 2. **Containers** — What are its internal containers (web app, mobile app, API, background worker, database, cache…)?
556
+ 3. **Users** — Which users interact directly with which containers?
557
+ 4. **Integrations** — Which external systems do the containers communicate with?
558
+
559
+ ## Step 2 — Build the diagram
560
+
561
+ ### Layout rules (grid = 40 units)
562
+ Place containers in a logical left-to-right or top-to-bottom flow:
563
+ - **Frontend / Browser / Mobile**: x: -320, y: 0. Type: box. Color: c-sky.
564
+ - **API / Backend**: x: 0, y: 0. Type: box. Color: c-blue.
565
+ - **Database**: x: 320, y: 80. Type: database. Color: c-teal.
566
+ - **Cache / Queue**: x: 320, y: -80. Type: ellipse. Color: c-amber.
567
+ - **External actor** (user): x: -560, y: 0. Type: actor. Color: c-gray.
568
+ - **External system**: x: 0, y: 240. Type: box. Color: c-slate.
569
+ - Spread additional containers vertically by multiples of 160.
570
+ - All positions must be multiples of 40.
571
+
572
+ ### Edge rules
573
+ - Label every edge with the protocol or action: "HTTPS", "SQL", "REST", "publishes", "subscribes"…
574
+
575
+ ## Step 3 — Call \`create_diagram\` with \`diagramType: "container"\` and \`userRequestedExplicitly: true\`.
576
+ `.trim();
577
+ case 'generate-uml-diagram': {
578
+ const umlType = (args.umlType || '').trim().toLowerCase() || 'class';
579
+ return `
580
+ ${PREAMBLE}
581
+
582
+ ---
583
+
584
+ You are about to create a **UML ${umlType} diagram**.
585
+
586
+ ## ⚠️ Explicit-request check
587
+ Only proceed if the user explicitly asked for a *UML* diagram by name. Otherwise use \`generate-context-diagram\` instead.
588
+
589
+ ## Step 1 — Gather the facts from docs
590
+
591
+ Read the documents relevant to the UML ${umlType} diagram. For each element you plan to put on the diagram, make sure it exists in the documentation. Do not invent classes, states, or actors absent from the docs.
592
+
593
+ ## Step 2 — Apply the UML ${umlType} conventions
594
+
595
+ ${umlTypeGuidance(umlType)}
596
+
597
+ ### Common rules (all UML variants)
598
+ - Each edge must have a label describing the relationship or transition.
599
+ - Keep labels short; use C4-style multi-line labels for class/component descriptions when helpful.
600
+ - Use multiples of 40 for positions. Origin (0,0) = canvas center.
601
+
602
+ ## Step 3 — Call \`create_diagram\` with \`diagramType: "uml"\` and \`userRequestedExplicitly: true\`.
603
+ `.trim();
604
+ }
605
+ case 'update-diagram-from-docs':
606
+ return `
607
+ ${PREAMBLE}
608
+
609
+ ---
610
+
611
+ You are about to **update ${args.diagramId ? `diagram \`${args.diagramId}\`` : 'all existing diagrams'}** to reflect the current state of the documentation.
612
+
613
+ ## Step 1 — Inventory existing diagrams
614
+
615
+ ${args.diagramId
616
+ ? `1. Call \`read_diagram\` with id \`${args.diagramId}\` to load its current nodes and edges.`
617
+ : `1. Call \`list_diagrams\` to get all diagrams with their id and title.
618
+ 2. For each diagram, call \`read_diagram\` to load its current nodes and edges.`}
619
+
620
+ ## Step 2 — Gather current architecture knowledge
621
+
622
+ 1. Call \`list_documents\` to get all documents.
623
+ 2. Read the documents that are architecturally significant (ADRs, README, guides with integration or architecture tags).
624
+ 3. Ignore any document whose frontmatter contains \`status: SuperSeeded\`.
625
+
626
+ ## Step 3 — Compare and update
627
+
628
+ For each diagram in scope:
629
+
630
+ 1. **Identify the diagram type** from its title and content (Context, Container, Flow, ERD, UML…).
631
+ 2. **Compare** its nodes and edges against the current documentation:
632
+ - New containers, systems, or actors mentioned in the docs but missing?
633
+ - Nodes that no longer exist or have been renamed?
634
+ - Edge labels still accurate?
635
+ 3. **If up to date** → skip it, report "no changes needed".
636
+ 4. **If changes are needed** → call \`create_diagram\` with:
637
+ - The **same \`id\`** as the existing diagram (overwrites it in place).
638
+ - The same \`diagramType\`. For non-context types, include \`userRequestedExplicitly: true\` since the user is explicitly updating that diagram.
639
+ - The same title unless a rename is warranted.
640
+ - Updated nodes and edges, preserving \`x\`/\`y\` positions of unchanged nodes.
641
+
642
+ ## Step 4 — Report
643
+
644
+ Summarize which diagrams were updated (and what changed) and which were skipped (already up to date).
645
+ `.trim();
646
+ case 'flow':
647
+ return `
648
+ ${PREAMBLE}
649
+
650
+ ---
651
+
652
+ You are about to create a **linear flow diagram**.
653
+
654
+ ## Step 1 — Answer these questions first (ask the user only if not found in docs)
655
+
656
+ 1. **Process** — What process or workflow are we representing?
657
+ 2. **Steps** — What are the steps or stages in order?
658
+ 3. **Actors** — Are there human actors or external systems involved at any step?
659
+ 4. **Branches** — Are there decision points or alternative paths?
660
+
661
+ ## Step 2 — Build the diagram
662
+
663
+ ### Layout rules (grid = 40 units)
664
+ - Steps are laid out **left to right**, each separated by 240 units on X.
665
+ - All nodes at y: 0 unless a branch is needed (branch at y: ±160).
666
+ - First step: x: -480. Then x: -240, x: 0, x: 240, x: 480… (adjust origin to center the flow).
667
+ - Use type: box for process steps (color: c-blue), type: actor for human actors (color: c-gray), type: database for stores (color: c-teal).
668
+ - Decision diamonds are not a native shape — use ellipse (color: c-amber) to indicate a decision point.
669
+ - All positions must be multiples of 40.
670
+
671
+ ### Edge rules
672
+ - Edges are directional left-to-right.
673
+ - Label branches: "yes / no", "success / error", etc.
674
+
675
+ ## Step 3 — Call \`create_diagram\` with \`diagramType: "flow"\`.
676
+ `.trim();
677
+ case 'erd':
678
+ return `
679
+ ${PREAMBLE}
680
+
681
+ ---
682
+
683
+ You are about to create an **Entity-Relationship Diagram**.
684
+
685
+ ## Step 1 — Answer these questions first (ask the user only if not found in docs)
686
+
687
+ 1. **Domain** — What domain or bounded context does this ERD cover?
688
+ 2. **Entities** — What are the main entities (tables, aggregates)?
689
+ 3. **Relationships** — What are the relationships between them and their cardinalities (1:1, 1:N, N:M)?
690
+ 4. **Key attributes** — Are there important attributes worth labeling on the edges?
691
+
692
+ ## Step 2 — Build the diagram
693
+
694
+ ### Layout rules (grid = 40 units)
695
+ - Each entity is a box. Place them so related entities are close together.
696
+ - Suggested starting positions for up to 6 entities:
697
+ - top-left: x: -320, y: -200
698
+ - top-center: x: 0, y: -200
699
+ - top-right: x: 320, y: -200
700
+ - bottom-left: x: -320, y: 200
701
+ - bottom-center: x: 0, y: 200
702
+ - bottom-right: x: 320, y: 200
703
+ - All positions must be multiples of 40.
704
+ - Color: c-blue for main entities, c-green for junction/pivot tables, c-slate for lookup/reference tables.
705
+
706
+ ### Edge rules
707
+ - Label every edge with the cardinality and nature of the relationship:
708
+ "1:N", "N:M", "has many", "belongs to", "references", etc.
709
+ - Edges are undirected by convention in ERDs — leave \`label\` descriptive.
710
+
711
+ ## Step 3 — Call \`create_diagram\` with \`diagramType: "erd"\`.
712
+ `.trim();
713
+ case 'generate-screen-guide': {
714
+ const screenFile = (args.screenFile || '').trim();
715
+ const screenshotUrl = (args.screenshotUrl || '').trim();
716
+ return `
717
+ ## Screen-guide diagram — source code IS the reference
718
+
719
+ A screen guide is an annotated screenshot built in **three layers**:
720
+ 1. the screenshot image as background,
721
+ 2. translucent \`box\` overlays covering each major layout region (zones),
722
+ 3. \`post-it\` callouts for each first-level feature, linked to the UI by
723
+ free-end arrows.
724
+
725
+ **The source code is the authoritative reference**, not the Markdown docs.
726
+ No ADR describes every button.
727
+
728
+ ## ⚠️ Explicit-request check
729
+ Only proceed if the user explicitly asked for a *screen guide*, *UI guide*, or *annotated screenshot*.
730
+
731
+ ## Step 1 — Resolve the screen source
732
+
733
+ ${screenFile
734
+ ? `The user specified \`${screenFile}\`. Call \`read_source_file\` with \`path: "${screenFile}"\`.`
735
+ : `Ask the user which screen to document (e.g. \`src/frontend/index.html\`). Then call \`read_source_file\` on it.`}
736
+
737
+ If the screen pulls in components or partials, use \`search_source\` + \`read_source_file\` to follow them. Cap at ~5 files total — enough to identify zones and first-level features, not to trace every dependency.
738
+
739
+ ## Step 2 — Identify layout zones (YOU decide, do not ask)
740
+
741
+ Scan the screen structure for **major visual regions** that partition the layout. Typical zones:
742
+ - Left / right sidebar or drawer
743
+ - Top bar / header
744
+ - Main content area
745
+ - Footer
746
+ - Right panel
747
+
748
+ Pick **2–5 zones**. For each zone, capture:
749
+ - \`name\` — 1–3 words ("Top Bar", "Collapsible Drawer", "Main Page").
750
+ - \`color\` — one distinct color per zone. Suggested rotation: \`c-red, c-amber, c-cyan, c-sky, c-lime, c-teal\`. Never reuse a color between two zones.
751
+
752
+ You will need the zone's bounding box on the screenshot (left/top/width/height in pixels) — you'll compute that once the user provides the screenshot.
753
+
754
+ ## Step 3 — Identify first-level features (YOU decide, do not ask)
755
+
756
+ A **first-level feature** is:
757
+ - **Visible on screen** without any interaction (a button, toggle, input, primary navigation element, filter).
758
+ - **Changes user-facing behavior significantly** when used (navigates, filters, toggles mode, opens a panel, searches).
759
+
760
+ NOT a first-level feature:
761
+ - Decorative elements (logos, dividers, icons without action).
762
+ - Controls nested inside a panel/modal that only appears after clicking something.
763
+ - Pure labels / static text.
764
+ - Duplicate controls (if the same action has two buttons, count it once).
765
+
766
+ Typical count: **4–10** features. Do not pad with minor buttons; do not omit obvious ones.
767
+
768
+ For each feature, capture:
769
+ - \`name\` — 2–5 words, title-cased ("Collapsible Drawer", "Dark / Light Mode", "Text Search in all documents"). Multi-line via \`\\n\` allowed when needed.
770
+ - \`kind\`:
771
+ - \`interactive\` — standard button, link, input, toggle. **Default.**
772
+ - \`differentiating\` — a feature that distinguishes the product from alternatives ("Professional Diagram Editor", "Word Cloud Generator"). Reserve for the 1–3 truly distinguishing features.
773
+ - \`target\` — which UI element / zone it points to (used to place the anchor and the post-it).
774
+
775
+ **Color assignment for feature callouts:**
776
+ - \`interactive\` → \`c-amber\` or \`c-orange\` (yellow family). Default.
777
+ - \`differentiating\` → a distinct non-yellow color (\`c-purple\`, \`c-rose\`, \`c-red\`, \`c-sky\`, \`c-teal\`, \`c-green\`). Never yellow.
778
+
779
+ ## Step 4 — Request the screenshot and WAIT
780
+
781
+ Tell the user:
782
+
783
+ > I identified N zones and M first-level features in \`<file>\`:
784
+ > - Zones: [comma-separated names]
785
+ > - Features: [comma-separated names, annotated with "(diff)" for the differentiating ones]
786
+ > I now need a screenshot of this screen. Two options:
787
+ > (a) Save the PNG into \`./documentation/images/<name>.png\` inside your docs folder.
788
+ > (b) Paste or drop the image into any existing diagram in the editor — it uploads automatically and returns a URL like \`/images/xxx.png\`.
789
+ > Please reply with (1) the URL, and (2) the natural pixel width × height of the image.
790
+
791
+ **Then stop.** Do not call \`create_diagram\` yet.
792
+
793
+ ${screenshotUrl
794
+ ? `(The user already provided \`${screenshotUrl}\` — you still need the pixel dimensions to place zones correctly.)`
795
+ : ''}
796
+
797
+ ## Step 5 — Build the diagram
798
+
799
+ Coordinate system: screen-guide positions align to **screenshot pixels** (canvas centre is origin), NOT to the 40-unit grid. Use the pixel dimensions the user provided.
800
+
801
+ ### Nodes
802
+
803
+ **A. Background image** (one node, \`locked\`):
804
+ \`\`\`json
805
+ { "type": "image", "name": "screenshot", "imageSrc": "<URL>",
806
+ "width": <imgW>, "height": <imgH>, "x": 0, "y": 0, "locked": true }
807
+ \`\`\`
808
+
809
+ **B. Zone overlays** (one per zone, \`locked\`, translucent):
810
+ \`\`\`json
811
+ { "type": "box", "name": "", "color": "<zone color>",
812
+ "bgOpacity": 0.18, "locked": true,
813
+ "width": <zoneW>, "height": <zoneH>,
814
+ "x": <zoneCenterX>, "y": <zoneCenterY> }
815
+ \`\`\`
816
+
817
+ **C. Zone labels** (one post-it per zone, **same color as the zone**):
818
+ \`\`\`json
819
+ { "type": "post-it", "name": "<zone name>", "color": "<zone color>",
820
+ "x": <inside zone>, "y": <inside zone>, "locked": true }
821
+ \`\`\`
822
+
823
+ **D. Feature callouts** (one post-it per feature, placed **outside** the screenshot):
824
+ \`\`\`json
825
+ { "type": "post-it", "name": "<feature name>",
826
+ "color": "<c-amber for interactive, distinct non-yellow for differentiating>",
827
+ "x": <outside screenshot>, "y": <outside screenshot> }
828
+ \`\`\`
829
+ Spread them in horizontal bands above/below the image and/or vertical columns left/right of it. Keep callouts close to their target so the arrow reads naturally.
830
+
831
+ **E. Anchors** (one per feature callout, placed on the target pixel — 8×8, invisible at rest):
832
+ \`\`\`json
833
+ { "type": "anchor", "name": "a1", "color": "c-gray",
834
+ "x": <target pixel x>, "y": <target pixel y> }
835
+ \`\`\`
836
+ Use short unique names (\`a1\`, \`a2\`, …) — anchors are invisible so the label does not matter.
837
+
838
+ ### Edges
839
+
840
+ For each feature callout, emit one directed edge from the post-it to its anchor, with an **empty** label:
841
+ \`\`\`json
842
+ { "from": "<post-it name>", "to": "a1", "label": "" }
843
+ \`\`\`
844
+
845
+ If you do not know exact target coordinates, you may omit the anchor and the \`to\` field — the edge renders a free-end arrow the user can drag:
846
+ \`\`\`json
847
+ { "from": "<post-it name>", "label": "" }
848
+ \`\`\`
849
+
850
+ **Prefer anchors.** The free-end fallback is a shortcut when pixel targets are unknown.
851
+
852
+ **Never** point edges at the image node itself — every arrow would converge on the image centre.
853
+
854
+ ## Step 6 — Call \`create_diagram\`
855
+
856
+ \`\`\`json
857
+ {
858
+ "diagramType": "screen-guide",
859
+ "userRequestedExplicitly": true,
860
+ "title": "Screen guide — <screen name>",
861
+ "nodes": [ /* image + zone boxes + zone labels + feature callouts + anchors */ ],
862
+ "edges": [ /* one edge per feature callout → its anchor */ ]
863
+ }
864
+ \`\`\`
865
+ `.trim();
866
+ }
867
+ }
868
+ }
869
+ function umlTypeGuidance(umlType) {
870
+ switch (umlType) {
871
+ case 'class':
872
+ return `### UML class diagram
873
+ - Each class is a \`box\` (c-blue for domain classes, c-green for value objects, c-slate for interfaces).
874
+ - Node label: \`ClassName\\n[Class]\\n+ attr: Type\\n+ method(): Type\`.
875
+ - Edges: label relationships as "extends", "implements", "has 1", "has *", "uses".`;
876
+ case 'sequence':
877
+ return `### UML sequence diagram
878
+ - Each participant is a \`box\` (c-blue for systems, c-gray for actors).
879
+ - Arrange participants left-to-right at the same y (spacing 200).
880
+ - Edges are messages; the label is the method/event name and uses arrows top-down by ordering the edges in the array chronologically.`;
881
+ case 'state':
882
+ return `### UML state diagram
883
+ - Each state is an \`ellipse\` (c-amber).
884
+ - Start and end states are \`circle\` (c-slate for end, c-green for start).
885
+ - Edges are transitions; label with the event/trigger.`;
886
+ case 'activity':
887
+ return `### UML activity diagram
888
+ - Activities are \`box\` (c-blue).
889
+ - Decision nodes are \`ellipse\` (c-amber).
890
+ - Start/end are \`circle\` (c-green/c-slate).
891
+ - Edges labeled with the guard or action.`;
892
+ case 'use-case':
893
+ case 'usecase':
894
+ return `### UML use-case diagram
895
+ - Actors are \`actor\` (c-gray) on the left (x: -320).
896
+ - Use cases are \`ellipse\` (c-blue) in the center.
897
+ - The system boundary is implied by grouping — no explicit box needed.
898
+ - Edges between actor and use case labeled with the action ("initiates", "participates in").`;
899
+ default:
900
+ return `### UML ${umlType} diagram\nFollow the standard UML conventions for \`${umlType}\` diagrams. Use \`box\`, \`ellipse\`, \`actor\`, \`circle\`, or \`database\` shapes as appropriate; label every edge.`;
901
+ }
902
+ }
903
+ function createMcpServer(docsPath) {
904
+ const server = new index_js_1.Server({ name: 'living-documentation', version: '1.0.0' }, {
905
+ capabilities: { tools: {}, prompts: {} },
906
+ instructions: SERVER_GUIDE,
907
+ });
908
+ server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({ tools: TOOLS }));
909
+ server.setRequestHandler(types_js_1.ListPromptsRequestSchema, async () => ({ prompts: PROMPTS }));
910
+ server.setRequestHandler(types_js_1.GetPromptRequestSchema, async (request) => {
911
+ const name = request.params.name;
912
+ const prompt = PROMPTS.find(p => p.name === name);
913
+ if (!prompt)
914
+ throw new Error(`Unknown prompt: ${name}`);
915
+ const args = (request.params.arguments ?? {});
916
+ const text = buildPromptTemplate(name, args);
917
+ return {
918
+ description: prompt.description,
919
+ messages: [{ role: 'user', content: { type: 'text', text } }],
920
+ };
921
+ });
922
+ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
923
+ const { name, arguments: args = {} } = request.params;
924
+ try {
925
+ switch (name) {
926
+ case 'get_server_guide':
927
+ return { content: [{ type: 'text', text: SERVER_GUIDE }] };
928
+ case 'list_documents':
929
+ return (0, documents_1.toolListDocuments)(docsPath);
930
+ case 'read_document':
931
+ return (0, documents_1.toolReadDocument)(docsPath, args);
932
+ case 'create_document':
933
+ return (0, documents_1.toolCreateDocument)(docsPath, args);
934
+ case 'list_diagrams':
935
+ return (0, diagrams_1.toolListDiagrams)(docsPath);
936
+ case 'read_diagram':
937
+ return (0, diagrams_1.toolReadDiagram)(docsPath, args);
938
+ case 'create_diagram':
939
+ return (0, diagrams_1.toolCreateDiagram)(docsPath, args);
940
+ case 'list_source_files':
941
+ return (0, source_1.toolListSourceFiles)(docsPath, args);
942
+ case 'read_source_file':
943
+ return (0, source_1.toolReadSourceFile)(docsPath, args);
944
+ case 'search_source':
945
+ return (0, source_1.toolSearchSource)(docsPath, args);
946
+ default:
947
+ throw new Error(`Unknown tool: ${name}`);
948
+ }
949
+ }
950
+ catch (err) {
951
+ return {
952
+ content: [{ type: 'text', text: `Error: ${err instanceof Error ? err.message : String(err)}` }],
953
+ isError: true,
954
+ };
955
+ }
956
+ });
957
+ return server;
958
+ }
959
+ function mcpRouter(docsPath) {
960
+ const router = (0, express_1.Router)();
961
+ // Main MCP endpoint — stateless: one Server + Transport per request
962
+ router.post('/', async (req, res) => {
963
+ const server = createMcpServer(docsPath);
964
+ const transport = new streamableHttp_js_1.StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
965
+ try {
966
+ await server.connect(transport);
967
+ await transport.handleRequest(req, res, req.body);
968
+ }
969
+ finally {
970
+ await server.close();
971
+ }
972
+ });
973
+ // GET — surface a helpful message (Claude Desktop / browser landing)
974
+ router.get('/', (_req, res) => {
975
+ res.json({
976
+ mcp: 'living-documentation',
977
+ version: '1.0.0',
978
+ transport: 'streamable-http',
979
+ endpoint: 'POST /mcp',
980
+ tools: TOOLS.map(t => t.name),
981
+ prompts: PROMPTS.map(p => ({ name: p.name, description: p.description })),
982
+ });
983
+ });
984
+ return router;
985
+ }
986
+ //# sourceMappingURL=server.js.map