living-documentation 7.45.0 → 7.47.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 (84) hide show
  1. package/dist/src/frontend/context.html +420 -0
  2. package/dist/src/frontend/i18n/en.json +46 -0
  3. package/dist/src/frontend/i18n/fr.json +46 -0
  4. package/dist/src/frontend/index.html +9 -0
  5. package/dist/src/lib/config.js +2 -2
  6. package/dist/src/lib/config.js.map +1 -1
  7. package/dist/src/routes/context.d.ts +3 -0
  8. package/dist/src/routes/context.d.ts.map +1 -0
  9. package/dist/src/routes/context.js +245 -0
  10. package/dist/src/routes/context.js.map +1 -0
  11. package/dist/src/routes/documents.d.ts.map +1 -1
  12. package/dist/src/routes/documents.js +2 -1
  13. package/dist/src/routes/documents.js.map +1 -1
  14. package/dist/src/server.d.ts.map +1 -1
  15. package/dist/src/server.js +3 -0
  16. package/dist/src/server.js.map +1 -1
  17. package/dist/starting-doc/.living-doc.json +3 -3
  18. package/dist/starting-doc/ADRS/2026_01_01_[ADR]_example_architecture_decision.md +58 -0
  19. package/dist/starting-doc/AI/HOW_TO.md +338 -0
  20. package/dist/starting-doc/AI/default/AGENTS.md +14 -0
  21. package/dist/starting-doc/AI/default/CLAUDE.md +14 -0
  22. package/dist/starting-doc/AI/default/MEMORY.md +7 -0
  23. package/dist/starting-doc/AI/flavors/project-instructions-backend-api.md +41 -0
  24. package/dist/starting-doc/AI/flavors/project-instructions-frontend-app.md +42 -0
  25. package/dist/starting-doc/AI/flavors/project-instructions-library-cli.md +41 -0
  26. package/dist/starting-doc/AI/flavors/project-instructions-monorepo.md +41 -0
  27. package/dist/starting-doc/AI/project-instructions.md +78 -0
  28. package/dist/starting-doc/AI/rules/no-magic-numbers.md +18 -0
  29. package/package.json +1 -1
  30. package/dist/starting-doc/.annotations.json +0 -1
  31. package/dist/starting-doc/.diagrams.json +0 -2049
  32. package/dist/starting-doc/.metadata.json +0 -12
  33. package/dist/starting-doc/1_tutorial/2026_04_11_13_25_[General]_crer_vos_dossiers.md +0 -16
  34. package/dist/starting-doc/1_tutorial/2026_04_11_18_58_[General]_creer_un_document_dans_un_dossier.md +0 -8
  35. package/dist/starting-doc/1_tutorial/2026_04_12_09_00_[General]_editer_et_sauvegarder.md +0 -39
  36. package/dist/starting-doc/1_tutorial/2026_04_12_10_00_[General]_utiliser_les_snippets.md +0 -71
  37. package/dist/starting-doc/2026_04_08_20_52_[General]_welcome.md +0 -17
  38. package/dist/starting-doc/2026_04_11_12_55_[General]_premiers_pas.md +0 -271
  39. package/dist/starting-doc/2_guide/2026_04_08_00_04_[DOCUMENT]_utilisation_des_images_plein_ecran_lien_clickable.md +0 -40
  40. package/dist/starting-doc/2_guide/2026_04_08_23_38_[Configuration]_demarrage_de_living_documentation.md +0 -32
  41. package/dist/starting-doc/2_guide/2026_04_09_09_00_[NAVIGATION]_recherche_plein_texte.md +0 -65
  42. package/dist/starting-doc/2_guide/2026_04_09_10_00_[EXPORT]_exporter_en_pdf.md +0 -43
  43. package/dist/starting-doc/2_guide/2026_04_09_11_00_[Configuration]_configurer_le_panneau_admin.md +0 -55
  44. package/dist/starting-doc/2_guide/2026_04_09_12_00_[Configuration]_extra_files.md +0 -68
  45. package/dist/starting-doc/2_guide/2026_04_09_13_00_[WORDCLOUD]_word_cloud.md +0 -54
  46. package/dist/starting-doc/2_guide/2026_04_09_14_00_[DIAGRAM]_creer_et_lier_un_diagramme.md +0 -77
  47. package/dist/starting-doc/3_concept/2026_04_08_20_58_[DOCUMENTING]_ADRS.md +0 -20
  48. package/dist/starting-doc/3_concept/2026_04_08_22_15_[DOCUMENTING]_living_documentation.md +0 -17
  49. package/dist/starting-doc/3_concept/2026_04_08_22_46_[METHODOLOGY]_diataxis_architecture_du_contenu.md +0 -16
  50. package/dist/starting-doc/4_reference/2026_04_08_23_14_[FUNDAMENTALS]_the_living_documentation_tool.md +0 -41
  51. package/dist/starting-doc/4_reference/2026_04_09_01_00_[REFERENCE]_raccourcis_clavier.md +0 -61
  52. package/dist/starting-doc/4_reference/2026_04_09_02_00_[REFERENCE]_tokens_pattern_nommage.md +0 -75
  53. package/dist/starting-doc/4_reference/2026_04_09_03_00_[REFERENCE]_types_de_snippets.md +0 -68
  54. package/dist/starting-doc/4_reference/2026_04_11_17_31_[FUNDAMENTALS]_architecturer_une_documentation.md +0 -12
  55. package/dist/starting-doc/4_reference/2026_04_12_14_07_[FUNDAMENTALS]_dossiers_et_catgories.md +0 -89
  56. package/dist/starting-doc/5_talks/2026_04_28_09_48_[CONFERENCE]_demo_living_documentation_mcp_en_conference.md +0 -312
  57. package/dist/starting-doc/images/admin_screenshot.png +0 -0
  58. package/dist/starting-doc/images/ajout-document.png +0 -0
  59. package/dist/starting-doc/images/ajouter-document-categorie.png +0 -0
  60. package/dist/starting-doc/images/ajouter_un_document_dans_un_dossier.png +0 -0
  61. package/dist/starting-doc/images/architecturer_une_documentation_reference.png +0 -0
  62. package/dist/starting-doc/images/cr_er_un_document.png +0 -0
  63. package/dist/starting-doc/images/creation-nouveau-dossier.png +0 -0
  64. package/dist/starting-doc/images/creer-document-context-engineering.png +0 -0
  65. package/dist/starting-doc/images/creer-dossier-only-tutoriel.png +0 -0
  66. package/dist/starting-doc/images/creer-dossier-tutoriel.png +0 -0
  67. package/dist/starting-doc/images/creer-dossiers-done.png +0 -0
  68. package/dist/starting-doc/images/creer-un-document.png +0 -0
  69. package/dist/starting-doc/images/creer-vos-dossiers-tutoriel.png +0 -0
  70. package/dist/starting-doc/images/creer-vos-dossiers.png +0 -0
  71. package/dist/starting-doc/images/decouverte_adrs.png +0 -0
  72. package/dist/starting-doc/images/diataxis.png +0 -0
  73. package/dist/starting-doc/images/diataxis_callout.png +0 -0
  74. package/dist/starting-doc/images/document-cree.png +0 -0
  75. package/dist/starting-doc/images/liens_snippets.png +0 -0
  76. package/dist/starting-doc/images/living_documentation.png +0 -0
  77. package/dist/starting-doc/images/living_documentation_context_demo_conf.png +0 -0
  78. package/dist/starting-doc/images/npm_logo.png +0 -0
  79. package/dist/starting-doc/images/popup-creer-document.png +0 -0
  80. package/dist/starting-doc/images/popup-creer-dossier.png +0 -0
  81. package/dist/starting-doc/images/popup-dossier-cree.png +0 -0
  82. package/dist/starting-doc/images/quatre-dossiers-crees.png +0 -0
  83. package/dist/starting-doc/images/screenshot-living-doc.png +0 -0
  84. package/dist/starting-doc/images/the_living_documentation_tool.png +0 -0
@@ -0,0 +1,420 @@
1
+ <!doctype html>
2
+ <html lang="fr">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>AI Context</title>
7
+ <script src="/i18n.js"></script>
8
+ <script src="/confirm-modal.js"></script>
9
+ <script src="https://cdn.tailwindcss.com?plugins=typography"></script>
10
+ <script>
11
+ tailwind.config = { darkMode: "class", theme: { extend: {} } };
12
+ </script>
13
+ </head>
14
+ <body class="min-h-screen bg-gray-50 text-gray-900 dark:bg-gray-950 dark:text-gray-100">
15
+ <header class="h-14 border-b border-gray-200 bg-white dark:border-gray-800 dark:bg-gray-900 flex items-center gap-3 px-4">
16
+ <a href="/" class="text-sm font-medium text-gray-500 hover:text-blue-600 dark:text-gray-400 dark:hover:text-blue-400" data-i18n="context.back_to_docs">Back to docs</a>
17
+ <h1 class="text-base font-semibold" data-i18n="context.title">AI Context</h1>
18
+ <span id="status" class="ml-auto text-xs text-gray-500"></span>
19
+ </header>
20
+
21
+ <main class="max-w-7xl mx-auto px-4 py-5 space-y-6">
22
+ <section class="space-y-1">
23
+ <h2 class="text-xl font-semibold" data-i18n="context.orientation_title">AI orientation</h2>
24
+ <p class="text-sm text-gray-500 dark:text-gray-400" data-i18n="context.orientation_intro">Stable instructions and rules for AI-assisted development.</p>
25
+ </section>
26
+
27
+ <section class="grid min-w-0 grid-cols-1 xl:grid-cols-[minmax(0,1fr)_24rem] gap-5">
28
+ <div class="min-w-0 space-y-5">
29
+ <section class="min-w-0 rounded-lg border border-gray-200 bg-white dark:border-gray-800 dark:bg-gray-900 p-4">
30
+ <div class="flex items-center justify-between gap-3 mb-3">
31
+ <h2 class="text-sm font-semibold" data-i18n="context.instructions_title">Instruction files</h2>
32
+ <div class="flex items-center gap-3">
33
+ <span id="instructionCount" class="text-xs text-gray-500"></span>
34
+ <button id="btnToggleInstructionBrowser" class="rounded-md border border-gray-300 px-2 py-1 text-xs font-semibold text-gray-600 hover:bg-gray-50 dark:border-gray-700 dark:text-gray-300 dark:hover:bg-gray-800" data-i18n="context.add_instruction_file">Add AI instruction file</button>
35
+ </div>
36
+ </div>
37
+ <div id="instructionBrowser" class="hidden mb-3 rounded-lg border border-gray-200 dark:border-gray-700 overflow-hidden">
38
+ <div class="flex items-center gap-2 px-3 py-2 bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700">
39
+ <button id="instructionBrowseUp" class="text-xs text-blue-600 dark:text-blue-400 hover:underline disabled:opacity-30 disabled:pointer-events-none shrink-0">
40
+ <span data-i18n="common.up">↑ Up</span>
41
+ </button>
42
+ <span id="instructionBrowsePath" class="font-mono text-xs text-gray-400 dark:text-gray-500 truncate flex-1 text-right"></span>
43
+ </div>
44
+ <div id="instructionBrowseList" class="divide-y divide-gray-100 dark:divide-gray-800 max-h-52 overflow-y-auto"></div>
45
+ </div>
46
+ <div id="instructionList" class="space-y-2"></div>
47
+ </section>
48
+
49
+ <section class="min-w-0 rounded-lg border border-gray-200 bg-white dark:border-gray-800 dark:bg-gray-900 p-4">
50
+ <div class="flex items-center justify-between gap-3 mb-3">
51
+ <h2 class="text-sm font-semibold" data-i18n="context.rules_title">AI rules</h2>
52
+ <span id="rulesFolder" class="font-mono text-xs text-gray-400"></span>
53
+ </div>
54
+ <div id="ruleList" class="space-y-2"></div>
55
+ </section>
56
+ </div>
57
+
58
+ <aside class="min-w-0 max-w-full space-y-5">
59
+ <section class="min-w-0 rounded-lg border border-gray-200 bg-white dark:border-gray-800 dark:bg-gray-900 p-4 space-y-3">
60
+ <h2 class="text-sm font-semibold" data-i18n="context.add_rule_title">Add AI rule</h2>
61
+ <div>
62
+ <label for="ruleTitle" class="block text-xs font-semibold text-gray-500 mb-1" data-i18n="context.rule_title_label">Title</label>
63
+ <input id="ruleTitle" class="min-w-0 w-full h-9 rounded-md border border-gray-300 bg-white px-2 text-sm dark:border-gray-700 dark:bg-gray-950" data-i18n-placeholder="context.rule_title_placeholder" placeholder="Avoid magic numbers" />
64
+ </div>
65
+ <div>
66
+ <label for="ruleSeverity" class="block text-xs font-semibold text-gray-500 mb-1" data-i18n="context.rule_severity_label">Severity</label>
67
+ <select id="ruleSeverity" class="min-w-0 w-full h-9 rounded-md border border-gray-300 bg-white px-2 text-sm dark:border-gray-700 dark:bg-gray-950">
68
+ <option value="guideline" data-i18n="context.rule_severity_guideline">Guideline</option>
69
+ <option value="warning" data-i18n="context.rule_severity_warning">Warning</option>
70
+ <option value="required" data-i18n="context.rule_severity_required">Required</option>
71
+ </select>
72
+ </div>
73
+ <div>
74
+ <label for="ruleDescription" class="block text-xs font-semibold text-gray-500 mb-1" data-i18n="context.rule_description_label">Description</label>
75
+ <input id="ruleDescription" class="min-w-0 w-full h-9 rounded-md border border-gray-300 bg-white px-2 text-sm dark:border-gray-700 dark:bg-gray-950" data-i18n-placeholder="context.rule_description_placeholder" placeholder="Name domain constants instead of repeating raw values." />
76
+ </div>
77
+ <div>
78
+ <label for="ruleTags" class="block text-xs font-semibold text-gray-500 mb-1" data-i18n="context.rule_tags_label">Tags</label>
79
+ <input id="ruleTags" class="min-w-0 w-full h-9 rounded-md border border-gray-300 bg-white px-2 text-sm dark:border-gray-700 dark:bg-gray-950" data-i18n-placeholder="context.rule_tags_placeholder" placeholder="code-quality, maintainability" />
80
+ </div>
81
+ <div>
82
+ <label for="ruleAppliesTo" class="block text-xs font-semibold text-gray-500 mb-1" data-i18n="context.rule_applies_to_label">Applies to</label>
83
+ <input id="ruleAppliesTo" class="min-w-0 w-full h-9 rounded-md border border-gray-300 bg-white px-2 text-sm dark:border-gray-700 dark:bg-gray-950" data-i18n-placeholder="context.rule_applies_to_placeholder" placeholder="src/**/*.ts, src/frontend/**/*.js" />
84
+ </div>
85
+ <div>
86
+ <label for="ruleBody" class="block text-xs font-semibold text-gray-500 mb-1" data-i18n="context.rule_body_label">Rule body</label>
87
+ <textarea id="ruleBody" rows="7" class="min-w-0 w-full rounded-md border border-gray-300 bg-white px-2 py-2 text-sm dark:border-gray-700 dark:bg-gray-950" data-i18n-placeholder="context.rule_body_placeholder" placeholder="Numeric constants with domain meaning should be named."></textarea>
88
+ </div>
89
+ <button id="btnAddRule" class="w-full h-9 rounded-md bg-blue-600 text-sm font-semibold text-white hover:bg-blue-700" data-i18n="context.add_rule_button">Add rule</button>
90
+ </section>
91
+ </aside>
92
+ </section>
93
+ </main>
94
+
95
+ <div
96
+ id="confirm-modal"
97
+ class="hidden fixed inset-0 z-[60] bg-black/50 flex items-center justify-center p-4"
98
+ onclick="_confirmModalBackdrop(event)"
99
+ >
100
+ <div
101
+ class="w-full max-w-md bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded-xl shadow-2xl p-5 flex flex-col gap-3"
102
+ onclick="event.stopPropagation()"
103
+ >
104
+ <h3 id="confirm-modal-title" class="font-semibold text-gray-900 dark:text-gray-100"></h3>
105
+ <p id="confirm-modal-message" class="text-sm text-gray-700 dark:text-gray-200"></p>
106
+ <p id="confirm-modal-detail" class="text-xs text-gray-500 dark:text-gray-400 italic break-all"></p>
107
+ <div class="flex justify-end gap-2 mt-2">
108
+ <button
109
+ id="confirm-modal-cancel"
110
+ type="button"
111
+ class="text-sm px-3 py-1.5 rounded-lg border border-gray-200 dark:border-gray-700 text-gray-600 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors"
112
+ ></button>
113
+ <button
114
+ id="confirm-modal-ok"
115
+ type="button"
116
+ class="text-sm px-4 py-1.5 rounded-lg text-white font-semibold transition-colors"
117
+ ></button>
118
+ </div>
119
+ </div>
120
+ </div>
121
+
122
+ <script>
123
+ const els = {
124
+ status: document.getElementById('status'),
125
+ instructionList: document.getElementById('instructionList'),
126
+ instructionCount: document.getElementById('instructionCount'),
127
+ instructionBrowser: document.getElementById('instructionBrowser'),
128
+ instructionBrowseUp: document.getElementById('instructionBrowseUp'),
129
+ instructionBrowsePath: document.getElementById('instructionBrowsePath'),
130
+ instructionBrowseList: document.getElementById('instructionBrowseList'),
131
+ btnToggleInstructionBrowser: document.getElementById('btnToggleInstructionBrowser'),
132
+ ruleList: document.getElementById('ruleList'),
133
+ rulesFolder: document.getElementById('rulesFolder'),
134
+ ruleTitle: document.getElementById('ruleTitle'),
135
+ ruleSeverity: document.getElementById('ruleSeverity'),
136
+ ruleDescription: document.getElementById('ruleDescription'),
137
+ ruleTags: document.getElementById('ruleTags'),
138
+ ruleAppliesTo: document.getElementById('ruleAppliesTo'),
139
+ ruleBody: document.getElementById('ruleBody'),
140
+ btnAddRule: document.getElementById('btnAddRule'),
141
+ };
142
+ let orientation = null;
143
+ let instructionBrowseCurrent = '';
144
+ let instructionBrowseParent = '';
145
+
146
+ function setStatus(message) {
147
+ els.status.textContent = message || '';
148
+ }
149
+
150
+ function escapeHtml(value) {
151
+ return String(value ?? '').replace(/[&<>"']/g, (char) => ({
152
+ '&': '&amp;',
153
+ '<': '&lt;',
154
+ '>': '&gt;',
155
+ '"': '&quot;',
156
+ "'": '&#39;',
157
+ }[char]));
158
+ }
159
+
160
+ function splitList(value) {
161
+ return value.split(',').map((item) => item.trim()).filter(Boolean);
162
+ }
163
+
164
+ function basename(value) {
165
+ return String(value || '').split(/[\\/]/).pop() || '';
166
+ }
167
+
168
+ function documentHref(docPath) {
169
+ const docId = encodeURIComponent(String(docPath || '').replace(/\.md$/i, ''));
170
+ return '/?doc=' + encodeURIComponent(docId);
171
+ }
172
+
173
+ function formatMessage(key, values) {
174
+ return Object.entries(values || {}).reduce(
175
+ (message, [name, value]) => message.replaceAll(`{${name}}`, value),
176
+ window.t(key),
177
+ );
178
+ }
179
+
180
+ function rootLabel(value) {
181
+ return window.t(`context.root.${value}`);
182
+ }
183
+
184
+ function typeLabel(value) {
185
+ return window.t(`context.type.${value}`);
186
+ }
187
+
188
+ function severityLabel(value) {
189
+ return window.t(`context.rule_severity_${value}`) === `context.rule_severity_${value}`
190
+ ? value
191
+ : window.t(`context.rule_severity_${value}`);
192
+ }
193
+
194
+ function renderEmpty(container, key) {
195
+ container.innerHTML = `<p class="text-sm text-gray-400">${window.t(key)}</p>`;
196
+ }
197
+
198
+ function renderInstructionFiles(items) {
199
+ els.instructionCount.textContent = `${items.filter((item) => item.exists).length}/${items.length}`;
200
+ if (!items.length) {
201
+ renderEmpty(els.instructionList, 'context.no_instructions');
202
+ return;
203
+ }
204
+ els.instructionList.innerHTML = items.map((item) => {
205
+ const statusClass = item.exists ? 'text-green-600 dark:text-green-400' : 'text-red-600 dark:text-red-400';
206
+ const statusLabel = item.exists ? window.t('context.exists') : window.t('context.missing');
207
+ const size = item.size === null ? '' : ` · ${Math.round(item.size / 1024)} KB`;
208
+ return `
209
+ <div class="flex items-start justify-between gap-3 rounded-md border border-gray-100 dark:border-gray-800 px-3 py-2">
210
+ <div class="min-w-0">
211
+ <a href="${escapeHtml(documentHref(item.path))}" class="font-mono text-xs break-all text-blue-600 hover:underline dark:text-blue-400">${escapeHtml(item.path)}</a>
212
+ <div class="text-xs text-gray-400">${escapeHtml(rootLabel(item.root))} · ${escapeHtml(typeLabel(item.type))}${size}</div>
213
+ </div>
214
+ <div class="flex items-center gap-3 shrink-0">
215
+ <span class="text-xs font-semibold ${statusClass}">${statusLabel}</span>
216
+ ${
217
+ item.exists
218
+ ? `<button data-filename="${escapeHtml(basename(item.path))}" class="instruction-remove text-xs text-red-500 hover:text-red-700 dark:hover:text-red-400">${window.t('common.remove')}</button>`
219
+ : ''
220
+ }
221
+ </div>
222
+ </div>
223
+ `;
224
+ }).join('');
225
+ els.instructionList.querySelectorAll('.instruction-remove').forEach((button) => {
226
+ button.addEventListener('click', () => removeInstructionFile(button.dataset.filename));
227
+ });
228
+ }
229
+
230
+ async function loadInstructionBrowse(dirPath) {
231
+ els.instructionBrowseList.innerHTML = `<p class="px-3 py-4 text-xs text-gray-400 text-center">${window.t('common.loading')}</p>`;
232
+ try {
233
+ const data = await fetch('/api/browse?path=' + encodeURIComponent(dirPath)).then((res) => res.json());
234
+ instructionBrowseCurrent = data.current;
235
+ instructionBrowseParent = data.parent;
236
+ els.instructionBrowsePath.textContent = data.current;
237
+ els.instructionBrowseUp.disabled = !data.parent;
238
+
239
+ const instructionNames = new Set(((orientation && orientation.instructions) || []).map((item) => basename(item.path)));
240
+ const rows = [];
241
+ for (const dir of data.dirs || []) {
242
+ rows.push(`
243
+ <button data-path="${escapeHtml(dir.path)}" class="instruction-dir w-full flex items-center gap-2 px-3 py-2 text-sm text-left hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors">
244
+ <span class="text-gray-400 shrink-0">&#128193;</span>
245
+ <span class="text-gray-700 dark:text-gray-300 truncate">${escapeHtml(dir.name)}</span>
246
+ </button>
247
+ `);
248
+ }
249
+ for (const file of data.files || []) {
250
+ const added = instructionNames.has(file.name);
251
+ rows.push(`
252
+ <div class="flex items-center justify-between gap-2 px-3 py-2 text-sm hover:bg-gray-50 dark:hover:bg-gray-800">
253
+ <span class="flex items-center gap-2 text-gray-700 dark:text-gray-300 min-w-0">
254
+ <span class="text-gray-400 shrink-0">&#128196;</span>
255
+ <span class="truncate">${escapeHtml(file.name)}</span>
256
+ </span>
257
+ ${
258
+ added
259
+ ? `<span class="text-xs text-green-600 dark:text-green-400 shrink-0">${window.t('context.added')}</span>`
260
+ : `<button data-path="${escapeHtml(file.path)}" class="instruction-add text-xs text-blue-600 dark:text-blue-400 hover:underline shrink-0">${window.t('context.add_file_action')}</button>`
261
+ }
262
+ </div>
263
+ `);
264
+ }
265
+
266
+ els.instructionBrowseList.innerHTML = rows.length
267
+ ? rows.join('')
268
+ : `<p class="px-3 py-4 text-xs text-gray-400 text-center">${window.t('common.empty_dir')}</p>`;
269
+
270
+ els.instructionBrowseList.querySelectorAll('.instruction-dir').forEach((button) => {
271
+ button.addEventListener('click', () => loadInstructionBrowse(button.dataset.path));
272
+ });
273
+ els.instructionBrowseList.querySelectorAll('.instruction-add').forEach((button) => {
274
+ button.addEventListener('click', () => addInstructionFile(button.dataset.path));
275
+ });
276
+ } catch {
277
+ els.instructionBrowseList.innerHTML = `<p class="px-3 py-4 text-xs text-red-400 text-center">${window.t('common.cannot_read_dir')}</p>`;
278
+ }
279
+ }
280
+
281
+ function toggleInstructionBrowser() {
282
+ const isHidden = els.instructionBrowser.classList.toggle('hidden');
283
+ els.btnToggleInstructionBrowser.textContent = window.t(isHidden ? 'context.add_instruction_file' : 'context.hide_instruction_browser');
284
+ if (!isHidden && !instructionBrowseCurrent && orientation && orientation.sourceRoot) {
285
+ loadInstructionBrowse(orientation.sourceRoot);
286
+ }
287
+ }
288
+
289
+ async function addInstructionFile(filePath) {
290
+ setStatus(window.t('context.adding_instruction_file'));
291
+ const res = await fetch('/api/context/instructions', {
292
+ method: 'POST',
293
+ headers: { 'Content-Type': 'application/json' },
294
+ body: JSON.stringify({ path: filePath }),
295
+ });
296
+ if (!res.ok) throw new Error(await res.text());
297
+ await loadOrientation();
298
+ if (!els.instructionBrowser.classList.contains('hidden')) {
299
+ await loadInstructionBrowse(instructionBrowseCurrent);
300
+ }
301
+ }
302
+
303
+ async function removeInstructionFile(filename) {
304
+ const ok = await window.showConfirm({
305
+ title: window.t('context.remove_instruction_title'),
306
+ message: formatMessage('context.remove_instruction_message', { name: filename }),
307
+ detail: window.t('context.remove_instruction_detail'),
308
+ confirmLabel: window.t('common.remove'),
309
+ danger: true,
310
+ });
311
+ if (!ok) return;
312
+
313
+ setStatus(window.t('context.removing_instruction_file'));
314
+ const res = await fetch('/api/context/instructions/' + encodeURIComponent(filename), {
315
+ method: 'DELETE',
316
+ });
317
+ if (!res.ok) throw new Error(await res.text());
318
+ await loadOrientation();
319
+ if (!els.instructionBrowser.classList.contains('hidden')) {
320
+ await loadInstructionBrowse(instructionBrowseCurrent);
321
+ }
322
+ }
323
+
324
+ function renderRules(items) {
325
+ if (!items.length) {
326
+ renderEmpty(els.ruleList, 'context.no_rules');
327
+ return;
328
+ }
329
+ els.ruleList.innerHTML = items.map((rule) => `
330
+ <article class="rounded-md border border-gray-100 dark:border-gray-800 px-3 py-2">
331
+ <div class="flex items-start justify-between gap-3">
332
+ <div class="min-w-0">
333
+ <h3 class="text-sm font-semibold">
334
+ <a href="${escapeHtml(documentHref(rule.path))}" class="text-blue-600 hover:underline dark:text-blue-400">${escapeHtml(rule.title)}</a>
335
+ </h3>
336
+ <a href="${escapeHtml(documentHref(rule.path))}" class="font-mono text-xs text-gray-400 hover:text-blue-600 dark:hover:text-blue-400 break-all">${escapeHtml(rule.path)}</a>
337
+ </div>
338
+ <span class="rounded bg-gray-100 px-2 py-1 text-xs font-semibold text-gray-600 dark:bg-gray-800 dark:text-gray-300">${escapeHtml(severityLabel(rule.severity))}</span>
339
+ </div>
340
+ <p class="mt-2 text-sm text-gray-600 dark:text-gray-300">${escapeHtml(rule.description)}</p>
341
+ <div class="mt-2 flex flex-wrap gap-1 text-xs text-blue-600 dark:text-blue-400">
342
+ ${(rule.tags || []).map((tag) => `<span>${escapeHtml(tag)}</span>`).join('')}
343
+ </div>
344
+ <div class="mt-2 font-mono text-xs text-gray-400 break-all">${escapeHtml((rule.appliesTo || []).join(', '))}</div>
345
+ </article>
346
+ `).join('');
347
+ }
348
+
349
+ function renderOrientation(data) {
350
+ orientation = data;
351
+ renderInstructionFiles(data.instructions || []);
352
+ renderRules(data.rules || []);
353
+ els.rulesFolder.textContent = data.rulesFolder || '';
354
+ }
355
+
356
+ async function loadOrientation() {
357
+ setStatus(window.t('context.loading'));
358
+ const res = await fetch('/api/context/orientation');
359
+ if (!res.ok) throw new Error(await res.text());
360
+ renderOrientation(await res.json());
361
+ setStatus('');
362
+ }
363
+
364
+ async function addRule() {
365
+ const payload = {
366
+ title: els.ruleTitle.value.trim(),
367
+ severity: els.ruleSeverity.value,
368
+ description: els.ruleDescription.value.trim(),
369
+ tags: splitList(els.ruleTags.value),
370
+ appliesTo: splitList(els.ruleAppliesTo.value),
371
+ body: els.ruleBody.value.trim(),
372
+ };
373
+ if (!payload.title) {
374
+ setStatus(window.t('context.rule_title_required'));
375
+ return;
376
+ }
377
+ setStatus(window.t('context.saving_rule'));
378
+ const res = await fetch('/api/context/rules', {
379
+ method: 'POST',
380
+ headers: { 'Content-Type': 'application/json' },
381
+ body: JSON.stringify(payload),
382
+ });
383
+ if (!res.ok) throw new Error(await res.text());
384
+ els.ruleTitle.value = '';
385
+ els.ruleDescription.value = '';
386
+ els.ruleTags.value = '';
387
+ els.ruleAppliesTo.value = '';
388
+ els.ruleBody.value = '';
389
+ await loadOrientation();
390
+ }
391
+
392
+ async function loadContextI18n() {
393
+ try {
394
+ const cfgRes = await fetch('/api/config');
395
+ const cfg = cfgRes.ok ? await cfgRes.json() : {};
396
+ await window.initI18n(cfg.language || 'en');
397
+ } catch {
398
+ await window.initI18n('en');
399
+ }
400
+ window.applyI18n();
401
+ document.title = window.t('context.title');
402
+ }
403
+
404
+ async function init() {
405
+ await loadContextI18n();
406
+ await loadOrientation();
407
+ }
408
+
409
+ els.btnAddRule.addEventListener('click', () => {
410
+ addRule().catch((err) => setStatus(err.message));
411
+ });
412
+ els.btnToggleInstructionBrowser.addEventListener('click', toggleInstructionBrowser);
413
+ els.instructionBrowseUp.addEventListener('click', () => {
414
+ if (instructionBrowseParent) loadInstructionBrowse(instructionBrowseParent);
415
+ });
416
+
417
+ init().catch((err) => setStatus(err.message));
418
+ </script>
419
+ </body>
420
+ </html>
@@ -29,6 +29,7 @@
29
29
  "nav.new_document": "New document",
30
30
  "nav.word_cloud": "☁ Word Cloud",
31
31
  "nav.diagram": "◇ Diagram",
32
+ "nav.ai_context": "AI Context",
32
33
  "nav.files": "📁 Metadata Files",
33
34
  "nav.admin": "⚙ Admin",
34
35
 
@@ -111,6 +112,51 @@
111
112
  "accuracy.label": "Reliability",
112
113
  "accuracy.tooltip": "Unchanged: {unchanged} · Modified: {modified} · Missing: {missing} · Total: {total}",
113
114
 
115
+ "context.back_to_docs": "Back to docs",
116
+ "context.title": "AI Context",
117
+ "context.orientation_title": "AI orientation",
118
+ "context.orientation_intro": "Stable instructions and rules for AI-assisted development.",
119
+ "context.instructions_title": "Instruction files",
120
+ "context.add_instruction_file": "Add AI instruction file",
121
+ "context.hide_instruction_browser": "Hide file browser",
122
+ "context.rules_title": "AI rules",
123
+ "context.add_rule_title": "Add AI rule",
124
+ "context.add_rule_button": "Add rule",
125
+ "context.loading": "Loading…",
126
+ "context.empty": "Nothing listed.",
127
+ "context.exists": "Found",
128
+ "context.missing": "Missing",
129
+ "context.root.sourceRoot": "Source root",
130
+ "context.root.docsFolder": "Docs folder",
131
+ "context.type.file": "File",
132
+ "context.type.directory": "Directory",
133
+ "context.type.missing": "Missing",
134
+ "context.no_rules": "No AI rules yet. Add one to create documentation/AI/rules/*.md.",
135
+ "context.no_instructions": "No AI instruction files yet. Add one to link a document under AI/.",
136
+ "context.add_file_action": "+ Add",
137
+ "context.added": "Added",
138
+ "context.adding_instruction_file": "Adding instruction file…",
139
+ "context.removing_instruction_file": "Removing instruction file…",
140
+ "context.remove_instruction_title": "Remove instruction file",
141
+ "context.remove_instruction_message": "Remove \"{name}\" from AI instructions?",
142
+ "context.remove_instruction_detail": "The symbolic link under AI/ will be deleted. The original file is kept.",
143
+ "context.rule_title_label": "Title",
144
+ "context.rule_title_placeholder": "Avoid magic numbers",
145
+ "context.rule_severity_label": "Severity",
146
+ "context.rule_severity_guideline": "Guideline",
147
+ "context.rule_severity_warning": "Warning",
148
+ "context.rule_severity_required": "Required",
149
+ "context.rule_description_label": "Description",
150
+ "context.rule_description_placeholder": "Name domain constants instead of repeating raw values.",
151
+ "context.rule_tags_label": "Tags",
152
+ "context.rule_tags_placeholder": "code-quality, maintainability",
153
+ "context.rule_applies_to_label": "Applies to",
154
+ "context.rule_applies_to_placeholder": "src/**/*.ts, src/frontend/**/*.js",
155
+ "context.rule_body_label": "Rule body",
156
+ "context.rule_body_placeholder": "Numeric constants with domain meaning should be named.",
157
+ "context.rule_title_required": "Rule title is required.",
158
+ "context.saving_rule": "Saving rule…",
159
+
114
160
  "modal.new_folder.title": "New folder",
115
161
  "modal.new_folder.name_label": "Folder name",
116
162
  "modal.new_folder.name_placeholder": "my-folder",
@@ -29,6 +29,7 @@
29
29
  "nav.new_document": "Nouveau document",
30
30
  "nav.word_cloud": "☁ Nuage de mots",
31
31
  "nav.diagram": "◇ Diagramme",
32
+ "nav.ai_context": "Contexte IA",
32
33
  "nav.files": "📁 Fichiers Métadonnées",
33
34
  "nav.admin": "⚙ Admin",
34
35
 
@@ -111,6 +112,51 @@
111
112
  "accuracy.label": "Fiabilité",
112
113
  "accuracy.tooltip": "Inchangés : {unchanged} · Modifiés : {modified} · Manquants : {missing} · Total : {total}",
113
114
 
115
+ "context.back_to_docs": "Retour aux docs",
116
+ "context.title": "Contexte IA",
117
+ "context.orientation_title": "Orientation IA",
118
+ "context.orientation_intro": "Instructions et règles stables pour le développement assisté par IA.",
119
+ "context.instructions_title": "Fichiers d'instructions",
120
+ "context.add_instruction_file": "Ajouter un fichier d'instruction IA",
121
+ "context.hide_instruction_browser": "Masquer le navigateur",
122
+ "context.rules_title": "Règles IA",
123
+ "context.add_rule_title": "Ajouter une règle IA",
124
+ "context.add_rule_button": "Ajouter la règle",
125
+ "context.loading": "Chargement…",
126
+ "context.empty": "Aucun élément.",
127
+ "context.exists": "Trouvé",
128
+ "context.missing": "Manquant",
129
+ "context.root.sourceRoot": "Racine des sources",
130
+ "context.root.docsFolder": "Dossier docs",
131
+ "context.type.file": "Fichier",
132
+ "context.type.directory": "Dossier",
133
+ "context.type.missing": "Manquant",
134
+ "context.no_rules": "Aucune règle IA pour le moment. Ajoutez-en une pour créer documentation/AI/rules/*.md.",
135
+ "context.no_instructions": "Aucun fichier d'instruction IA pour le moment. Ajoutez-en un pour lier un document dans AI/.",
136
+ "context.add_file_action": "+ Ajouter",
137
+ "context.added": "Ajouté",
138
+ "context.adding_instruction_file": "Ajout du fichier d'instruction…",
139
+ "context.removing_instruction_file": "Retrait du fichier d'instruction…",
140
+ "context.remove_instruction_title": "Retirer le fichier d'instruction",
141
+ "context.remove_instruction_message": "Retirer « {name} » des instructions IA ?",
142
+ "context.remove_instruction_detail": "Le lien symbolique dans AI/ sera supprimé. Le fichier original est conservé.",
143
+ "context.rule_title_label": "Titre",
144
+ "context.rule_title_placeholder": "Éviter les magic numbers",
145
+ "context.rule_severity_label": "Sévérité",
146
+ "context.rule_severity_guideline": "Règle",
147
+ "context.rule_severity_warning": "Avertissement",
148
+ "context.rule_severity_required": "Obligatoire",
149
+ "context.rule_description_label": "Description",
150
+ "context.rule_description_placeholder": "Nommer les constantes métier au lieu de répéter des valeurs brutes.",
151
+ "context.rule_tags_label": "Tags",
152
+ "context.rule_tags_placeholder": "qualité-code, maintenabilité",
153
+ "context.rule_applies_to_label": "S'applique à",
154
+ "context.rule_applies_to_placeholder": "src/**/*.ts, src/frontend/**/*.js",
155
+ "context.rule_body_label": "Corps de la règle",
156
+ "context.rule_body_placeholder": "Les constantes numériques qui portent un sens métier doivent être nommées.",
157
+ "context.rule_title_required": "Le titre de la règle est obligatoire.",
158
+ "context.saving_rule": "Enregistrement de la règle…",
159
+
114
160
  "modal.new_folder.title": "Nouveau dossier",
115
161
  "modal.new_folder.name_label": "Nom du dossier",
116
162
  "modal.new_folder.name_placeholder": "mon-dossier",
@@ -441,6 +441,15 @@
441
441
  &#9671; Diagram
442
442
  </a>
443
443
 
444
+ <!-- AI Context -->
445
+ <a
446
+ href="/context"
447
+ data-i18n="nav.ai_context"
448
+ class="text-sm px-3 py-1.5 rounded-lg text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors font-medium"
449
+ >
450
+ AI Context
451
+ </a>
452
+
444
453
  <!-- Files -->
445
454
  <button
446
455
  onclick="openFilesModal()"
@@ -59,12 +59,12 @@ const STORAGE_DEFAULTS = {
59
59
  showDiagramDebug: false,
60
60
  diagramNodePalette: DEFAULT_DIAGRAM_NODE_PALETTE,
61
61
  diagramEdgePalette: DEFAULT_DIAGRAM_EDGE_PALETTE,
62
- sourceRoot: null,
62
+ sourceRoot: "..",
63
63
  blockedFileExtensions: DEFAULT_BLOCKED_FILE_EXTENSIONS,
64
64
  exclusiveFolderExpansion: false,
65
65
  exclusiveCategoryExpansion: false,
66
66
  codeBlockMaxHeight: 400,
67
- markdownSoftBreaks: false,
67
+ markdownSoftBreaks: true,
68
68
  };
69
69
  function getConfigPath(docsPath) {
70
70
  return path_1.default.join(docsPath, CONFIG_FILENAME);
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/lib/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/lib/config.ts"],"names":[],"mappings":";;;;;AAgGA,sCAEC;AAuGD,gCAmBC;AAID,kCAkBC;AAlPD,4CAAoB;AACpB,gDAAwB;AAgCxB,MAAM,eAAe,GAAG,kBAAkB,CAAC;AAE3C,mGAAmG;AACnG,yFAAyF;AACzF,MAAM,4BAA4B,GAAG;IACnC,SAAS,EAAE,WAAW;IACtB,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,UAAU;IACrB,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,QAAQ;IACnB,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,UAAU;IACrB,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,UAAU;IACrB,SAAS,EAAE,WAAW;IACtB,SAAS,EAAE,QAAQ;IACnB,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,WAAW;CACvB,CAAC;AAEF,MAAM,4BAA4B,GAAG;IACnC,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;CACV,CAAC;AAEF,MAAM,+BAA+B,GAAG;IACtC,KAAK;IACL,IAAI;IACJ,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;CACN,CAAC;AAEF,MAAM,gBAAgB,GAAiB;IACrC,eAAe,EAAE,mCAAmC;IACpD,KAAK,EAAE,sBAAsB;IAC7B,KAAK,EAAE,QAAQ;IACf,QAAQ,EAAE,IAAI;IACd,IAAI,EAAE,IAAI;IACV,UAAU,EAAE,EAAE;IACd,gBAAgB,EAAE,KAAK;IACvB,kBAAkB,EAAE,4BAA4B;IAChD,kBAAkB,EAAE,4BAA4B;IAChD,UAAU,EAAE,IAAI;IAChB,qBAAqB,EAAE,+BAA+B;IACtD,wBAAwB,EAAE,KAAK;IAC/B,0BAA0B,EAAE,KAAK;IACjC,kBAAkB,EAAE,GAAG;IACvB,kBAAkB,EAAE,IAAI;CACzB,CAAC;AAEF,SAAgB,aAAa,CAAC,QAAgB;IAC5C,OAAO,cAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,OAAO,CAAC,CAAS;IACxB,OAAO,CAAC,CAAC,KAAK,CAAC,cAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,iBAAiB,CAAC,QAAgB,EAAE,GAAW;IACtD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,cAAI,CAAC,QAAQ,CAAC,cAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,cAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;QACrE,IAAI,cAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QACtC,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,QAAgB,EAAE,GAAW;IACpD,OAAO,cAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;AACrC,CAAC;AAED,sFAAsF;AACtF,oFAAoF;AACpF,SAAS,cAAc,CAAC,QAAgB;IACtC,MAAM,UAAU,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IAC3C,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,OAAO,EAAE,GAAG,gBAAgB,EAAE,CAAC;IACjC,CAAC;IACD,IAAI,GAA4B,CAAC;IACjC,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,GAAG,gBAAgB,EAAE,CAAC;IACjC,CAAC;IACD,IAAI,KAAK,GAAG,KAAK,CAAC;IAElB,6EAA6E;IAC7E,IAAI,YAAY,IAAI,GAAG,EAAE,CAAC;QACxB,OAAO,GAAG,CAAC,UAAU,CAAC;QACtB,KAAK,GAAG,IAAI,CAAC;IACf,CAAC;IAED,8EAA8E;IAC9E,IAAI,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ,IAAI,cAAI,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;QAC1E,MAAM,GAAG,GAAG,iBAAiB,CAAC,QAAQ,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;QACxD,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,IAAI,CACV,wDAAwD,GAAG,GAAG,CAC/D,CAAC;YACF,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;QACvB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CACV,qFAAqF,CACtF,CAAC;YACF,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC;QACxB,CAAC;QACD,KAAK,GAAG,IAAI,CAAC;IACf,CAAC;IAED,yFAAyF;IACzF,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,UAAuB,EAAE,CAAC;YAChD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC9B,OAAO,GAAG,IAAI,CAAC;gBACf,SAAS;YACX,CAAC;YACD,IAAI,cAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC3B,MAAM,GAAG,GAAG,iBAAiB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;gBAC/C,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;oBACjB,OAAO,CAAC,IAAI,CACV,kDAAkD,GAAG,GAAG,CACzD,CAAC;oBACF,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACrB,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,IAAI,CACV,6CAA6C,KAAK,kBAAkB,CACrE,CAAC;gBACJ,CAAC;gBACD,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;iBAAM,CAAC;gBACN,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;gBAClC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBAC1B,IAAI,UAAU,KAAK,KAAK;oBAAE,OAAO,GAAG,IAAI,CAAC;YAC3C,CAAC;QACH,CAAC;QACD,IAAI,OAAO,EAAE,CAAC;YACZ,GAAG,CAAC,UAAU,GAAG,QAAQ,CAAC;YAC1B,KAAK,GAAG,IAAI,CAAC;QACf,CAAC;IACH,CAAC;IAED,IAAI,KAAK,EAAE,CAAC;QACV,IAAI,CAAC;YACH,YAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QACtE,CAAC;QAAC,MAAM,CAAC;YACP,4EAA4E;QAC9E,CAAC;IACH,CAAC;IAED,OAAO,EAAE,GAAG,gBAAgB,EAAE,GAAI,GAA6B,EAAE,CAAC;AACpE,CAAC;AAED,SAAgB,UAAU,CAAC,QAAgB;IACzC,MAAM,MAAM,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IACxC,MAAM,WAAW,GAAG,cAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC3C,MAAM,UAAU,GACd,MAAM,CAAC,UAAU,KAAK,IAAI;QACxB,CAAC,CAAC,cAAI,CAAC,OAAO,CAAC,WAAW,CAAC;QAC3B,CAAC,CAAC,eAAe,CAAC,WAAW,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IACtD,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAC/C,eAAe,CAAC,WAAW,EAAE,GAAG,CAAC,CAClC,CAAC;IACF,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,IAAI,EAAE,GAAG,MAAM,CAAC;IACzE,KAAK,QAAQ,CAAC;IACd,KAAK,UAAU,CAAC;IAChB,OAAO;QACL,GAAG,IAAI;QACP,UAAU,EAAE,WAAW;QACvB,UAAU;QACV,UAAU;KACX,CAAC;AACJ,CAAC;AAED,gFAAgF;AAChF,sFAAsF;AACtF,SAAgB,WAAW,CACzB,QAAgB,EAChB,KAA4B;IAE5B,MAAM,MAAM,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IACxC,MAAM,OAAO,GAAiB,EAAE,GAAG,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IACtD,IAAI,YAAY,IAAI,KAAK,IAAI,OAAO,OAAO,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;QACpE,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACnD,CAAC;IACD,IAAI,YAAY,IAAI,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/D,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACjE,CAAC;IACD,YAAE,CAAC,aAAa,CACd,aAAa,CAAC,QAAQ,CAAC,EACvB,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAChC,OAAO,CACR,CAAC;IACF,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Router } from "express";
2
+ export declare function contextRouter(docsPath: string): Router;
3
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/routes/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AA4NjC,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CA2DtD"}