living-ai-documentation 1.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 (203) hide show
  1. package/LICENSE +661 -0
  2. package/README.fr.md +344 -0
  3. package/README.md +344 -0
  4. package/dist/bin/cli.d.ts +3 -0
  5. package/dist/bin/cli.d.ts.map +1 -0
  6. package/dist/bin/cli.js +262 -0
  7. package/dist/bin/cli.js.map +1 -0
  8. package/dist/src/frontend/accuracy-gauge.js +70 -0
  9. package/dist/src/frontend/admin.html +1532 -0
  10. package/dist/src/frontend/annotations.js +585 -0
  11. package/dist/src/frontend/boot.js +101 -0
  12. package/dist/src/frontend/config.js +29 -0
  13. package/dist/src/frontend/confirm-modal.js +82 -0
  14. package/dist/src/frontend/context.html +1252 -0
  15. package/dist/src/frontend/dark-mode.js +20 -0
  16. package/dist/src/frontend/diagram/alignment.js +161 -0
  17. package/dist/src/frontend/diagram/clipboard.js +187 -0
  18. package/dist/src/frontend/diagram/constants.js +109 -0
  19. package/dist/src/frontend/diagram/custom-shapes.js +104 -0
  20. package/dist/src/frontend/diagram/debug.js +43 -0
  21. package/dist/src/frontend/diagram/drawio-export.js +649 -0
  22. package/dist/src/frontend/diagram/edge-panel.js +293 -0
  23. package/dist/src/frontend/diagram/edge-rendering.js +12 -0
  24. package/dist/src/frontend/diagram/evidence.js +146 -0
  25. package/dist/src/frontend/diagram/grid.js +78 -0
  26. package/dist/src/frontend/diagram/groups.js +102 -0
  27. package/dist/src/frontend/diagram/history.js +157 -0
  28. package/dist/src/frontend/diagram/image-name-modal.js +48 -0
  29. package/dist/src/frontend/diagram/image-upload.js +36 -0
  30. package/dist/src/frontend/diagram/label-editor.js +115 -0
  31. package/dist/src/frontend/diagram/link-panel.js +144 -0
  32. package/dist/src/frontend/diagram/main.js +364 -0
  33. package/dist/src/frontend/diagram/network.js +2214 -0
  34. package/dist/src/frontend/diagram/node-panel.js +389 -0
  35. package/dist/src/frontend/diagram/node-rendering.js +964 -0
  36. package/dist/src/frontend/diagram/persistence.js +168 -0
  37. package/dist/src/frontend/diagram/ports.js +421 -0
  38. package/dist/src/frontend/diagram/selection-overlay.js +387 -0
  39. package/dist/src/frontend/diagram/state.js +43 -0
  40. package/dist/src/frontend/diagram/t.js +3 -0
  41. package/dist/src/frontend/diagram/toast.js +21 -0
  42. package/dist/src/frontend/diagram/unlock-hold.js +206 -0
  43. package/dist/src/frontend/diagram/zoom.js +20 -0
  44. package/dist/src/frontend/diagram-link-modal.js +137 -0
  45. package/dist/src/frontend/diagram.html +1494 -0
  46. package/dist/src/frontend/documents.js +479 -0
  47. package/dist/src/frontend/export.js +338 -0
  48. package/dist/src/frontend/file-attach.js +178 -0
  49. package/dist/src/frontend/files-modal.js +243 -0
  50. package/dist/src/frontend/i18n/en.json +624 -0
  51. package/dist/src/frontend/i18n/fr.json +624 -0
  52. package/dist/src/frontend/i18n.js +32 -0
  53. package/dist/src/frontend/image-paste.js +126 -0
  54. package/dist/src/frontend/index.html +2806 -0
  55. package/dist/src/frontend/local-search.js +476 -0
  56. package/dist/src/frontend/metadata.js +318 -0
  57. package/dist/src/frontend/misc.js +92 -0
  58. package/dist/src/frontend/new-doc-modal.js +285 -0
  59. package/dist/src/frontend/new-folder-modal.js +169 -0
  60. package/dist/src/frontend/search.js +194 -0
  61. package/dist/src/frontend/shape-editor.html +685 -0
  62. package/dist/src/frontend/sidebar-helpers.js +96 -0
  63. package/dist/src/frontend/sidebar-resize.js +98 -0
  64. package/dist/src/frontend/sidebar.js +351 -0
  65. package/dist/src/frontend/snippet-detect.js +25 -0
  66. package/dist/src/frontend/snippet-table.js +85 -0
  67. package/dist/src/frontend/snippet-tree.js +94 -0
  68. package/dist/src/frontend/snippets.js +1146 -0
  69. package/dist/src/frontend/state.js +46 -0
  70. package/dist/src/frontend/utils.js +21 -0
  71. package/dist/src/frontend/validate.js +107 -0
  72. package/dist/src/frontend/vendor/wordcloud2.js +1187 -0
  73. package/dist/src/frontend/wordcloud.js +693 -0
  74. package/dist/src/lib/config.d.ts +26 -0
  75. package/dist/src/lib/config.d.ts.map +1 -0
  76. package/dist/src/lib/config.js +195 -0
  77. package/dist/src/lib/config.js.map +1 -0
  78. package/dist/src/lib/hash.d.ts +2 -0
  79. package/dist/src/lib/hash.d.ts.map +1 -0
  80. package/dist/src/lib/hash.js +18 -0
  81. package/dist/src/lib/hash.js.map +1 -0
  82. package/dist/src/lib/metadata.d.ts +31 -0
  83. package/dist/src/lib/metadata.d.ts.map +1 -0
  84. package/dist/src/lib/metadata.js +128 -0
  85. package/dist/src/lib/metadata.js.map +1 -0
  86. package/dist/src/lib/parser.d.ts +11 -0
  87. package/dist/src/lib/parser.d.ts.map +1 -0
  88. package/dist/src/lib/parser.js +111 -0
  89. package/dist/src/lib/parser.js.map +1 -0
  90. package/dist/src/lib/status.d.ts +9 -0
  91. package/dist/src/lib/status.d.ts.map +1 -0
  92. package/dist/src/lib/status.js +72 -0
  93. package/dist/src/lib/status.js.map +1 -0
  94. package/dist/src/mcp/server.d.ts +3 -0
  95. package/dist/src/mcp/server.d.ts.map +1 -0
  96. package/dist/src/mcp/server.js +2046 -0
  97. package/dist/src/mcp/server.js.map +1 -0
  98. package/dist/src/mcp/tools/diagrams.d.ts +82 -0
  99. package/dist/src/mcp/tools/diagrams.d.ts.map +1 -0
  100. package/dist/src/mcp/tools/diagrams.js +594 -0
  101. package/dist/src/mcp/tools/diagrams.js.map +1 -0
  102. package/dist/src/mcp/tools/documents.d.ts +44 -0
  103. package/dist/src/mcp/tools/documents.d.ts.map +1 -0
  104. package/dist/src/mcp/tools/documents.js +186 -0
  105. package/dist/src/mcp/tools/documents.js.map +1 -0
  106. package/dist/src/mcp/tools/git.d.ts +10 -0
  107. package/dist/src/mcp/tools/git.d.ts.map +1 -0
  108. package/dist/src/mcp/tools/git.js +217 -0
  109. package/dist/src/mcp/tools/git.js.map +1 -0
  110. package/dist/src/mcp/tools/metadata.d.ts +57 -0
  111. package/dist/src/mcp/tools/metadata.d.ts.map +1 -0
  112. package/dist/src/mcp/tools/metadata.js +222 -0
  113. package/dist/src/mcp/tools/metadata.js.map +1 -0
  114. package/dist/src/mcp/tools/source.d.ts +29 -0
  115. package/dist/src/mcp/tools/source.d.ts.map +1 -0
  116. package/dist/src/mcp/tools/source.js +196 -0
  117. package/dist/src/mcp/tools/source.js.map +1 -0
  118. package/dist/src/routes/annotations.d.ts +3 -0
  119. package/dist/src/routes/annotations.d.ts.map +1 -0
  120. package/dist/src/routes/annotations.js +83 -0
  121. package/dist/src/routes/annotations.js.map +1 -0
  122. package/dist/src/routes/browse-source.d.ts +3 -0
  123. package/dist/src/routes/browse-source.d.ts.map +1 -0
  124. package/dist/src/routes/browse-source.js +79 -0
  125. package/dist/src/routes/browse-source.js.map +1 -0
  126. package/dist/src/routes/browse.d.ts +3 -0
  127. package/dist/src/routes/browse.d.ts.map +1 -0
  128. package/dist/src/routes/browse.js +91 -0
  129. package/dist/src/routes/browse.js.map +1 -0
  130. package/dist/src/routes/config.d.ts +3 -0
  131. package/dist/src/routes/config.d.ts.map +1 -0
  132. package/dist/src/routes/config.js +145 -0
  133. package/dist/src/routes/config.js.map +1 -0
  134. package/dist/src/routes/context.d.ts +3 -0
  135. package/dist/src/routes/context.d.ts.map +1 -0
  136. package/dist/src/routes/context.js +287 -0
  137. package/dist/src/routes/context.js.map +1 -0
  138. package/dist/src/routes/diagrams.d.ts +3 -0
  139. package/dist/src/routes/diagrams.d.ts.map +1 -0
  140. package/dist/src/routes/diagrams.js +69 -0
  141. package/dist/src/routes/diagrams.js.map +1 -0
  142. package/dist/src/routes/documents.d.ts +11 -0
  143. package/dist/src/routes/documents.d.ts.map +1 -0
  144. package/dist/src/routes/documents.js +450 -0
  145. package/dist/src/routes/documents.js.map +1 -0
  146. package/dist/src/routes/export.d.ts +3 -0
  147. package/dist/src/routes/export.d.ts.map +1 -0
  148. package/dist/src/routes/export.js +280 -0
  149. package/dist/src/routes/export.js.map +1 -0
  150. package/dist/src/routes/files.d.ts +3 -0
  151. package/dist/src/routes/files.d.ts.map +1 -0
  152. package/dist/src/routes/files.js +180 -0
  153. package/dist/src/routes/files.js.map +1 -0
  154. package/dist/src/routes/images.d.ts +3 -0
  155. package/dist/src/routes/images.d.ts.map +1 -0
  156. package/dist/src/routes/images.js +49 -0
  157. package/dist/src/routes/images.js.map +1 -0
  158. package/dist/src/routes/metadata.d.ts +3 -0
  159. package/dist/src/routes/metadata.d.ts.map +1 -0
  160. package/dist/src/routes/metadata.js +131 -0
  161. package/dist/src/routes/metadata.js.map +1 -0
  162. package/dist/src/routes/shape-libraries.d.ts +3 -0
  163. package/dist/src/routes/shape-libraries.d.ts.map +1 -0
  164. package/dist/src/routes/shape-libraries.js +118 -0
  165. package/dist/src/routes/shape-libraries.js.map +1 -0
  166. package/dist/src/routes/wordcloud.d.ts +3 -0
  167. package/dist/src/routes/wordcloud.d.ts.map +1 -0
  168. package/dist/src/routes/wordcloud.js +95 -0
  169. package/dist/src/routes/wordcloud.js.map +1 -0
  170. package/dist/src/server.d.ts +7 -0
  171. package/dist/src/server.d.ts.map +1 -0
  172. package/dist/src/server.js +93 -0
  173. package/dist/src/server.js.map +1 -0
  174. package/dist/starter-doc/.living-doc.json +52 -0
  175. package/dist/starter-doc/ADRS/2026_01_01_[ADR]_example_architecture_decision.md +59 -0
  176. package/dist/starter-doc/AI/2026_01_01_how_to.md +112 -0
  177. package/dist/starter-doc/AI/PROJECT-INSTRUCTIONS.md +172 -0
  178. package/dist/starter-doc/AI/PROJECT-STACK.md +77 -0
  179. package/dist/starter-doc/AI/PROJECT-USEFUL-COMMANDS.md +80 -0
  180. package/dist/starter-doc/AI/default/AGENTS.md +31 -0
  181. package/dist/starter-doc/AI/default/CLAUDE.md +31 -0
  182. package/dist/starter-doc/AI/default/MEMORY.md +24 -0
  183. package/dist/starter-doc/AI/rules/no-magic-numbers.md +18 -0
  184. package/dist/starter-doc/AI/rules/track-current-work.md +23 -0
  185. package/dist/starter-doc/WORKLOG/current-task.md +57 -0
  186. package/dist/starter-doc-fr/.living-doc.json +52 -0
  187. package/dist/starter-doc-fr/ADRS/2026_01_01_[ADR]_example_architecture_decision.md +59 -0
  188. package/dist/starter-doc-fr/AI/2026_01_01_how_to.md +100 -0
  189. package/dist/starter-doc-fr/AI/PROJECT-INSTRUCTIONS.md +172 -0
  190. package/dist/starter-doc-fr/AI/PROJECT-STACK.md +77 -0
  191. package/dist/starter-doc-fr/AI/PROJECT-USEFUL-COMMANDS.md +80 -0
  192. package/dist/starter-doc-fr/AI/default/AGENTS.md +31 -0
  193. package/dist/starter-doc-fr/AI/default/CLAUDE.md +31 -0
  194. package/dist/starter-doc-fr/AI/default/MEMORY.md +24 -0
  195. package/dist/starter-doc-fr/AI/rules/no-magic-numbers.md +18 -0
  196. package/dist/starter-doc-fr/AI/rules/track-current-work.md +23 -0
  197. package/dist/starter-doc-fr/WORKLOG/current-task.md +57 -0
  198. package/images/living_documentation.jpg +0 -0
  199. package/images/readme-extra-files.png +0 -0
  200. package/images/readme-filename-pattern.png +0 -0
  201. package/images/readme-intelligent-search-demo.jpg +0 -0
  202. package/images/readme-sidebar.png +0 -0
  203. package/package.json +72 -0
package/README.md ADDED
@@ -0,0 +1,344 @@
1
+ # Living Documentation
2
+
3
+ [🇫🇷 Lire en français](./README.fr.md)
4
+
5
+ > **Local Markdown documentation hub with a built-in MCP server — coding agents create ADRs, draw diagrams, and detect drift while you code.**
6
+
7
+ Markdown on disk, no cloud, no database, no build step. Point it at a folder, open `http://localhost:4321`. Plug any MCP-aware AI agent into it (Claude Code, Claude Desktop, Cursor…) and your documentation maintains itself as your code evolves.
8
+
9
+ ![npm](https://img.shields.io/npm/v/living-ai-documentation) ![Node.js](https://img.shields.io/badge/Node.js-18%2B-green) ![TypeScript](https://img.shields.io/badge/TypeScript-5.x-blue) ![License](https://img.shields.io/badge/License-AGPL--3.0-blue) ![MCP](https://img.shields.io/badge/MCP-Streamable_HTTP-purple)
10
+
11
+ ```bash
12
+ npx living-ai-documentation # interactive wizard (EN/FR)
13
+ npx living-ai-documentation ./docs # serve an existing folder
14
+ ```
15
+
16
+ ![Living Documentation viewer](./images/living_documentation.jpg)
17
+
18
+ ---
19
+
20
+ ## Two ways to use it
21
+
22
+ ### 1. With an AI coding agent — the killer feature
23
+
24
+ Living Documentation ships an **MCP server** on `POST /mcp`. Any MCP-aware agent can read, create and audit your project's documentation autonomously.
25
+
26
+ | You say… | The agent triggers… | What happens |
27
+ | ---------------------------------------------------------- | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
28
+ | _"feature done"_ / _"feature terminée"_ | `create-adr` | Searches existing ADRs, supersedes the obsolete one if any, writes a new ADR at `To be validated`, binds the source files via metadata. |
29
+ | _"audit the ADRs"_ / _"vérifie la fiabilité des ADR"_ | `audit-adrs-drift` | Lists every ADR below 80% reliability and brings each back in sync — re-baseline or supersede after your confirmation. |
30
+ | _"review this ADR"_ / _"vérifie la pertinence de cet ADR"_ | `review-adr-relevance` | Reviews a single ADR against the bound source files; refreshes hashes or proposes supersession. |
31
+ | _"backfill ADRs from git"_ / _"retrodocumente depuis git"_ | `retrodocument-adrs-from-git` | Walks git history oldest-first and creates ADRs for the durable decisions that were never documented. |
32
+ | _"give me the big picture"_ | `generate-context-diagram` | Creates a C4 context diagram **derived from the docs**, never invented. |
33
+
34
+ **All new ADRs land at `To be validated`.** _You_ promote them. The agent never promotes on your behalf.
35
+
36
+ ### 2. Solo, no AI
37
+
38
+ A personal docs hub: ADRs, meeting notes, dev journals, feature plans, architecture sketches — all kept as Markdown on disk, git-friendly, zero vendor lock-in. Inline editor, snippets, image paste, file attachments, diagram editor, full-text search, PDF/HTML/Notion/Confluence export.
39
+
40
+ The two modes mix freely: jot notes solo all week, then let your agent record the ADR when the feature actually lands.
41
+
42
+ ---
43
+
44
+ ## Quick start
45
+
46
+ ```bash
47
+ # Interactive wizard — creates a starter doc folder (EN or FR), scaffolds
48
+ # AGENTS.md / CLAUDE.md / memory/MEMORY.md at the project root and symlinks
49
+ # them into <docs>/AI/ so AI agents can find them.
50
+ npx living-ai-documentation
51
+
52
+ # Or serve an existing folder
53
+ npx living-ai-documentation ./docs
54
+ npx living-ai-documentation ./docs --port 4000 --open
55
+ ```
56
+
57
+ Then open [http://localhost:4321](http://localhost:4321) (viewer) and [http://localhost:4321/admin](http://localhost:4321/admin) (config).
58
+
59
+ > The folder argument must be a **relative path** (`./docs`, `../shared/docs`…). Absolute paths and `~` are rejected so the generated `.living-doc.json` stays portable and can be committed.
60
+
61
+ ### Install
62
+
63
+ ```bash
64
+ npx living-ai-documentation # zero-install
65
+ npm install -g living-ai-documentation # global
66
+ ```
67
+
68
+ ---
69
+
70
+ ## Connect your AI agent
71
+
72
+ ### Claude Code
73
+
74
+ ```bash
75
+ claude mcp add --transport http living-ai-documentation http://localhost:4321/mcp
76
+ ```
77
+
78
+ Or manually in `.claude/settings.json`:
79
+
80
+ ```json
81
+ {
82
+ "mcpServers": {
83
+ "living-ai-documentation": {
84
+ "type": "http",
85
+ "url": "http://localhost:4321/mcp"
86
+ }
87
+ }
88
+ }
89
+ ```
90
+
91
+ ### Claude Desktop
92
+
93
+ In `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS), then restart:
94
+
95
+ ```json
96
+ {
97
+ "mcpServers": {
98
+ "living-ai-documentation": {
99
+ "type": "http",
100
+ "url": "http://localhost:4321/mcp"
101
+ }
102
+ }
103
+ }
104
+ ```
105
+
106
+ ### Cursor, Continue, any MCP client
107
+
108
+ Use the same HTTP endpoint: `http://localhost:4321/mcp` (Streamable HTTP transport, stateless).
109
+
110
+ > The Living Documentation server must be running first (`npx living-ai-documentation ./docs`) before the agent connects.
111
+
112
+ ---
113
+
114
+ ## Core concepts
115
+
116
+ - **Markdown on disk** — each document is a `.md` file. Configuration lives in `.living-doc.json` next to it. Both are git-friendly.
117
+ - **Filename pattern** — default `YYYY_MM_DD_HH_mm_[Category]_title.md`. The pattern is configurable; date, category and title are parsed from it. Files that don't match still appear under **General**.
118
+ - **Folders → categories → docs** in the sidebar. Folder names become the labels; numeric prefixes (`1_TUTORIAL`, `2_REFERENCE`) control order without showing in the UI.
119
+ - **ADRs** are the canonical decision record. The MCP server enforces a normalized frontmatter (`**date:**`, `**status:**`, `**description:**`, `**tags:**`) and a `To be validated` initial status that only a human can promote.
120
+ - **`sourceRoot`** points to the project's code. The MCP source tools (`list_source_files`, `read_source_file`, `search_source`) and the metadata binding rely on it. Defaults to the parent of the docs folder.
121
+ - **Source-file metadata + reliability gauge** — bind a doc to the source files it describes. Each binding stores a SHA-256. The gauge in the doc header (`🔴 → 🟡 → 🟢`) reflects `unchanged / total`. As soon as one bound file is modified or deleted, drift is visible. **God files** (`package.json`, lock files, manifests, barrels) are excluded by convention.
122
+ - **Diagrams are derived views** — they cite the documents they're built from (`evidence`). They cannot introduce concepts absent from the docs.
123
+
124
+ ---
125
+
126
+ ## MCP reference
127
+
128
+ ### Tools (19)
129
+
130
+ | Group | Tool | Description |
131
+ | ---------------------- | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
132
+ | Onboarding | `get_server_guide` | Returns the server guide: workflow, conventions, diagram rules. |
133
+ | Documents | `list_documents` | Inventory: `id`, `title`, `category`, `folder`, `linkHref`. |
134
+ | | `read_document` | Raw Markdown content of a document. |
135
+ | | `create_document` | Create a new `.md` file (filename from configured pattern, optional `date` override for retrodoc). |
136
+ | | `update_document` | Overwrite an existing doc (drift correction, supersede). |
137
+ | Diagrams | `list_diagrams` | List saved diagrams. |
138
+ | | `read_diagram` | Read nodes + edges of one diagram. |
139
+ | | `create_diagram` | Create / overwrite a diagram (server-side guardrails enforce C4 progression and edge labels). |
140
+ | Source code (fallback) | `list_source_files` | List files under `sourceRoot` (ignored: `node_modules`, `dist`, `.git`…). |
141
+ | | `read_source_file` | Read a file under `sourceRoot`. |
142
+ | | `search_source` | Grep-like text search under `sourceRoot`. |
143
+ | Metadata | `list_metadata` | Source-file bindings of a doc. |
144
+ | | `get_accuracy` | Per-entry status (`unchanged` / `modified` / `missing`) + weighted accuracy ∈ [0, 1]. |
145
+ | | `add_metadata` | Bind a source file (path under `sourceRoot`), records SHA-256. **Skips god files.** |
146
+ | | `remove_metadata` | Detach a binding (idempotent — for renames/deletes). |
147
+ | | `refresh_metadata` | Re-hash every binding (re-baseline after an update). |
148
+ | ADR audit | `list_adrs_below_accuracy` | Up to 10 ADRs whose accuracy < 80%, sorted most-degraded first. Excludes `SuperSeeded` and non-ADRs. |
149
+ | | `review_adr_relevance` | Factual report on one ADR + drifted files to re-read. Returns a `state` to drive the LLM decision tree. |
150
+ | Retrodocumentation | `retrodocument_adrs_from_git` | Up to 200 git commits (oldest first) classified `candidate` / `trivial` / `merge`, with god-file flags. Used to backfill missing ADRs. |
151
+
152
+ ### Prompts (10)
153
+
154
+ | Group | Prompt | When |
155
+ | ------------- | ----------------------------- | --------------------------------------------------------------------------------------------------------- |
156
+ | ADR lifecycle | `create-adr` | A feature has just been implemented or modified. Records the decision, supersedes a prior ADR if any. |
157
+ | | `audit-adrs-drift` | Batch audit: bring every drifting ADR back to a clear state (re-baseline or user-confirmed supersession). |
158
+ | | `review-adr-relevance` | Single ADR review against its bound source files. |
159
+ | | `retrodocument-adrs-from-git` | Backfill ADRs from git history when the project lacks them. |
160
+ | Diagrams | `generate-context-diagram` | DEFAULT. C4 context diagram, gated server-side. |
161
+ | | `generate-container-diagram` | Explicit-only. C4 container diagram of one system. |
162
+ | | `generate-uml-diagram` | Explicit-only. UML class/sequence/state/activity/use-case. |
163
+ | | `generate-screen-guide` | Explicit-only. Annotated screenshot with post-it callouts. |
164
+ | | `update-diagram-from-docs` | Re-read source documents to update existing diagrams. |
165
+ | | `flow`, `erd` | Linear flow / entity-relationship diagrams. |
166
+
167
+ A `GET http://localhost:4321/mcp` returns the live tool + prompt schemas for inspection.
168
+
169
+ ---
170
+
171
+ ## Authoring features
172
+
173
+ - **Inline editor** — edit any doc in the browser, saves to disk instantly.
174
+ - **Snippets panel** (`🧩 Snippets`) — pre-built Markdown constructs at the cursor: collapsible blocks, links (in-doc, cross-doc, anchor), lists, code blocks, blockquotes, separators, images. Plus a **table editor** (dynamic grid → aligned Markdown table) and a **tree editor** (indentation → ASCII tree with `├──` / `└──`). Selecting an existing snippet **detects its type** and pre-fills the form for editing.
175
+ - **Image paste** — paste from clipboard while editing, auto-uploaded to `<docs>/images/`, inserted as Markdown.
176
+ - **File attachments** — drag, drop, paste or pick any non-image file (PDF, archive, office doc). Uploaded under `<docs>/files/`, inserted as a paperclip pill. Blocked extensions and size limits configurable in Admin.
177
+ - **Full-text search** — instant filename filter + server-side content search; for each file lists every occurrence, highlights and jumps to them.
178
+ - **`metadata://<filename>` search prefix** — reverse-lookup: which documents reference this attachment?
179
+ - **Annotations** — persistent highlight markers per document (yellow / pink / green / blue).
180
+ - **Anchor navigation** — `[label](#heading-slug)` scrolls correctly after async render; IDs auto-generated.
181
+ - **Dark mode** — follows system preference, manually toggleable. Syntax highlighting always dark.
182
+
183
+ ![Sidebar grouped by folder → category](./images/readme-sidebar.png)
184
+
185
+ ![Full-text search](./images/readme-intelligent-search-demo.jpg)
186
+
187
+ ---
188
+
189
+ ## Diagram editor
190
+
191
+ Built-in canvas diagram editor (vis-network), accessible at `/diagram?id=...`.
192
+
193
+ - **C4 progression enforced** — context first (default), container/component only on explicit request. UML on explicit request.
194
+ - **Architectural `kind` vs visual `renderAs`** — separate the concept (`software_system`, `database`, `queue`, `api`, `cloud_service`…) from the shape (`box`, `ellipse`, `database`, `actor`, `post-it`…). The MCP picks sensible defaults for each `kind`.
195
+ - **Evidence provenance** — every architectural node/edge can cite the document and section that justifies it. The editor surfaces missing-evidence warnings.
196
+ - **Custom shape libraries** at `/shape-editor` — define your own shapes (SVG icons, ports, default colors) and reuse them across diagrams.
197
+ - **Ports** for anchored edges, **alignment guides**, **undo/redo**, **snap-to-grid**, **paste images**, **PNG export**, **deep-link** to a diagram by id.
198
+
199
+ ---
200
+
201
+ ## File organization
202
+
203
+ ```
204
+ docs/
205
+ ├── 2024_01_15_09_30_[DevOps]_deploy.md → category: DevOps
206
+ ├── 1_tutorial/ → folder: Tutorial (prefix hidden in UI)
207
+ │ └── 2024_03_01_10_00_[Onboarding]_setup.md → folder: Tutorial / category: Onboarding
208
+ ├── adrs/
209
+ │ └── 2024_04_01_10_15_[Architecture]_event_sourcing.md
210
+ └── 2_reference/
211
+ └── api.md → folder: Reference / category: General
212
+ ```
213
+
214
+ - The `[Category]` tag is parsed from the filename regardless of the folder.
215
+ - Files without a `[Category]` fall under **General**. **General** is always rendered first.
216
+ - Folders are sorted alphabetically — prefix with `1_`, `2_`… to force an order; the prefix is hidden in the UI but visible on hover.
217
+ - Subdirectory nesting is supported recursively.
218
+
219
+ ![Filename pattern](./images/readme-filename-pattern.png)
220
+
221
+ ---
222
+
223
+ ## Configuration (`.living-doc.json`)
224
+
225
+ Created automatically in your docs folder on first run. Edit in the Admin panel or by hand.
226
+
227
+ ```json
228
+ {
229
+ "filenamePattern": "YYYY_MM_DD_HH_mm_[Category]_title",
230
+ "title": "Living Documentation",
231
+ "theme": "system",
232
+ "port": 4321,
233
+ "extraFiles": ["../README.md", "../CLAUDE.md"],
234
+ "sourceRoot": "../src",
235
+ "blockedFileExtensions": [".exe", ".bin"]
236
+ }
237
+ ```
238
+
239
+ | Field | Role |
240
+ | ----------------------- | ----------------------------------------------------------------------------------------------------------- |
241
+ | `filenamePattern` | Filename convention used to parse date / category / title. `[Category]` token mandatory, exactly once. |
242
+ | `extraFiles` | Ordered Markdown files **outside** the docs folder (e.g. `README.md`, `CLAUDE.md`). Shown in General first. |
243
+ | `sourceRoot` | Where your code lives (relative to docs folder). Defaults to `..`. Used by MCP source + metadata tools. |
244
+ | `blockedFileExtensions` | File-attachment safety list, editable from Admin. |
245
+
246
+ **All paths are relative POSIX** so `.living-doc.json` stays portable. Legacy absolute paths are silently migrated on first read.
247
+
248
+ ![Extra files](./images/readme-extra-files.png)
249
+
250
+ ---
251
+
252
+ ## Export
253
+
254
+ | Format | Endpoint | Notes |
255
+ | ---------------------- | --------------------------- | -------------------------------------------------- |
256
+ | PDF (per doc) | `POST /api/export/html` | Browser print dialog from the rendered HTML. |
257
+ | HTML — Notion mode | `POST /api/export/html` | Single HTML bundle suitable for Notion import. |
258
+ | HTML — Confluence mode | `POST /api/export/html` | Zipped HTML bundle suitable for Confluence import. |
259
+ | Markdown bundle | `POST /api/export/markdown` | Zip of every document with normalized links. |
260
+
261
+ ---
262
+
263
+ ## UI surfaces
264
+
265
+ | URL | Page |
266
+ | --------------- | -------------------------------------------------------------------------------------------- |
267
+ | `/` | Viewer — sidebar, document rendering, inline edit, snippets, search, attachments. |
268
+ | `/admin` | Config — title, theme, filename pattern, extra files, source root, file safety list. |
269
+ | `/diagram?id=` | Diagram editor (vis-network) with C4 conventions, ports, alignment guides, undo/redo. |
270
+ | `/shape-editor` | Custom shape library editor — SVG icons, default colors, ports. |
271
+ | `/context` | AI context page — instructions, rules, memory, **MCP explorer** (try tools live in-browser). |
272
+
273
+ ---
274
+
275
+ ## REST API
276
+
277
+ <details>
278
+ <summary>Full HTTP API (click to expand)</summary>
279
+
280
+ | Method | Endpoint | Description |
281
+ | -------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------ |
282
+ | `GET` | `/api/documents` | List documents with metadata (includes extra files). |
283
+ | `GET` | `/api/documents/:id` | Document content + rendered HTML. |
284
+ | `POST` | `/api/documents` | Create from `{ title, category, folder?, content?, date? }`. |
285
+ | `PUT` | `/api/documents/:id` | Save content to disk. |
286
+ | `DELETE` | `/api/documents/:id` | Delete a document. |
287
+ | `GET` | `/api/documents/search?q=` | Full-text search. |
288
+ | `GET` | `/api/config` | Read config. |
289
+ | `PUT` | `/api/config` | Update config (`title`, `theme`, `filenamePattern`, `extraFiles`, `sourceRoot`, `blockedFileExtensions`, …). |
290
+ | `GET` | `/api/browse?path=` | List directories and `.md` files at a path. |
291
+ | `POST` | `/api/browse/mkdir` | Create a folder under the docs root. |
292
+ | `POST` | `/api/images/upload` | Upload a base64 image → `<docs>/images/`. |
293
+ | `POST` | `/api/files/upload` | Upload a base64 attachment → `<docs>/files/`. |
294
+ | `GET` | `/api/files` | List every attachment (chronological). |
295
+ | `PUT` | `/api/files/:filename` | Replace an attachment. |
296
+ | `DELETE` | `/api/files/:filename` | Delete an attachment. |
297
+ | `GET` | `/api/metadata/:docId` | Reliability report for one doc. |
298
+ | `POST` | `/api/metadata/:docId` | Add or replace a binding. |
299
+ | `DELETE` | `/api/metadata/:docId` | Remove a binding. |
300
+ | `POST` | `/api/metadata/:docId/refresh` | Re-baseline hashes. |
301
+ | `GET` | `/api/browse-source?path=` | Navigate the source tree rooted at `sourceRoot`. |
302
+ | `GET` | `/api/diagrams` | List saved diagrams. |
303
+ | `GET` | `/api/diagrams/:id` | Read a single diagram (nodes + edges). |
304
+ | `PUT` | `/api/diagrams/:id` | Create or update a diagram. |
305
+ | `DELETE` | `/api/diagrams/:id` | Delete a diagram. |
306
+ | `GET` | `/api/shape-libraries` | List custom shape libraries. |
307
+ | `PUT` | `/api/shape-libraries/:id` | Save a shape library. |
308
+ | `GET` | `/api/annotations[/:docId]` | List annotations (all docs / one doc). |
309
+ | `POST` | `/api/annotations/:docId` | Add an annotation. |
310
+ | `DELETE` | `/api/annotations/:docId/:id` | Delete one annotation. |
311
+ | `POST` | `/api/export/html` | HTML export — Notion / Confluence modes. |
312
+ | `POST` | `/api/export/markdown` | Markdown bundle export. |
313
+ | `GET` | `/api/wordcloud?path=&ext=` | Recursively concatenate matching source files as raw text. |
314
+ | `POST` | `/mcp` | Model Context Protocol endpoint (Streamable HTTP). |
315
+ | `GET` | `/mcp` | Live tool + prompt schema summary. |
316
+
317
+ </details>
318
+
319
+ ---
320
+
321
+ ## Build & test
322
+
323
+ ```bash
324
+ git clone https://github.com/craftskillz/living-documentation.git
325
+ cd living-documentation
326
+ npm install
327
+ npm run setup-hooks # one-time: enable .githooks/ as core.hooksPath
328
+ npm run dev -- ./documentation # nodemon + ts-node, watches src + bin
329
+ npm run build # tsc → dist/ + copy frontend assets
330
+ npm run test:e2e # Playwright end-to-end (~3 s, ~30 MCP specs)
331
+ npm run test:coverage # c8 V8-native coverage
332
+ ```
333
+
334
+ End-to-end tests use **Playwright**. Each test spawns a real CLI child process against a fresh fixture on a random port — no leaking state, runs in parallel. Server-side coverage via **c8** (V8 native, ~72% baseline overall, 83% on `src/routes` and `src/lib`).
335
+
336
+ ### Contributing
337
+
338
+ This repository ships with a `pre-commit` hook (under `.githooks/`) that enforces the bilingual README contract: if you touch `README.md` you must also touch `README.fr.md`, and vice-versa. Run `npm run setup-hooks` once after cloning to activate it. The same check runs in CI on every PR (see `.github/workflows/readme-sync.yml`), so the rule is enforced even if a contributor forgets the local setup.
339
+
340
+ ---
341
+
342
+ ## License
343
+
344
+ [AGPL-3.0](./LICENSE) — © Youssef MEDAGHRI-ALAOUI.
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../bin/cli.ts"],"names":[],"mappings":""}
@@ -0,0 +1,262 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const commander_1 = require("commander");
8
+ const path_1 = __importDefault(require("path"));
9
+ const fs_1 = __importDefault(require("fs"));
10
+ const promises_1 = require("readline/promises");
11
+ const server_1 = require("../src/server");
12
+ // Handle SIGTERM gracefully so V8 flushes NODE_V8_COVERAGE (used by c8 in tests).
13
+ // Also good hygiene — without this, process exits with code 143 and Express sockets
14
+ // may be dropped mid-flight. process.exit(0) runs pending exit handlers.
15
+ process.once("SIGTERM", () => process.exit(0));
16
+ const program = new commander_1.Command();
17
+ function parseInitLanguage(value) {
18
+ const normalized = value.trim().toLowerCase();
19
+ if (normalized === "en" || normalized === "fr") {
20
+ return normalized;
21
+ }
22
+ return null;
23
+ }
24
+ function copyDir(src, dest) {
25
+ fs_1.default.mkdirSync(dest, { recursive: true });
26
+ for (const entry of fs_1.default.readdirSync(src)) {
27
+ const srcPath = path_1.default.join(src, entry);
28
+ const destPath = path_1.default.join(dest, entry);
29
+ if (fs_1.default.statSync(srcPath).isDirectory()) {
30
+ copyDir(srcPath, destPath);
31
+ }
32
+ else {
33
+ fs_1.default.copyFileSync(srcPath, destPath);
34
+ }
35
+ }
36
+ }
37
+ function docsFolderReference(docsPath) {
38
+ const projectRoot = path_1.default.dirname(docsPath);
39
+ return path_1.default.relative(projectRoot, docsPath).split(path_1.default.sep).join("/") || ".";
40
+ }
41
+ function replaceDocsFolderPlaceholders(rootPath, docsFolder) {
42
+ for (const entry of fs_1.default.readdirSync(rootPath, { withFileTypes: true })) {
43
+ const fullPath = path_1.default.join(rootPath, entry.name);
44
+ if (entry.isDirectory()) {
45
+ replaceDocsFolderPlaceholders(fullPath, docsFolder);
46
+ continue;
47
+ }
48
+ if (!entry.isFile() || path_1.default.extname(entry.name).toLowerCase() !== ".md") {
49
+ continue;
50
+ }
51
+ const content = fs_1.default.readFileSync(fullPath, "utf-8");
52
+ if (!content.includes("DOCS_FOLDER")) {
53
+ continue;
54
+ }
55
+ fs_1.default.writeFileSync(fullPath, content.split("DOCS_FOLDER").join(docsFolder), "utf-8");
56
+ }
57
+ }
58
+ function validateRelativeFolder(folder) {
59
+ if (path_1.default.isAbsolute(folder) || folder.startsWith("~")) {
60
+ console.error(`\nError: The docs folder must be a relative path (got: ${folder}).\n` +
61
+ ` Example: npx living-ai-documentation ./mydocs\n` +
62
+ ` Absolute paths are rejected so .living-doc.json stays portable across machines.\n`);
63
+ process.exit(1);
64
+ }
65
+ }
66
+ function scaffoldStarter(docsPath, initLanguage) {
67
+ const starterDir = initLanguage === "fr" ? "starter-doc-fr" : "starter-doc";
68
+ const starterDocPath = path_1.default.join(__dirname, "..", starterDir);
69
+ if (!fs_1.default.existsSync(starterDocPath)) {
70
+ console.error(`\nError: Starter template not found: ${starterDir}\n`);
71
+ process.exit(1);
72
+ }
73
+ copyDir(starterDocPath, docsPath);
74
+ console.log(`\nInitialized ${initLanguage} documentation project in ${docsPath}\n`);
75
+ }
76
+ function initInstructionFiles(docsPath) {
77
+ const projectRoot = path_1.default.dirname(docsPath);
78
+ const aiPath = path_1.default.join(docsPath, "AI");
79
+ return [
80
+ {
81
+ sourcePath: path_1.default.join(docsPath, "AI", "default", "AGENTS.md"),
82
+ copyPath: path_1.default.join(projectRoot, "AGENTS.md"),
83
+ aiLinkPath: path_1.default.join(aiPath, "AGENTS.md"),
84
+ aiLinkTarget: path_1.default.relative(aiPath, path_1.default.join(projectRoot, "AGENTS.md")),
85
+ },
86
+ {
87
+ sourcePath: path_1.default.join(docsPath, "AI", "default", "CLAUDE.md"),
88
+ copyPath: path_1.default.join(projectRoot, "CLAUDE.md"),
89
+ aiLinkPath: path_1.default.join(aiPath, "CLAUDE.md"),
90
+ aiLinkTarget: path_1.default.relative(aiPath, path_1.default.join(projectRoot, "CLAUDE.md")),
91
+ },
92
+ {
93
+ sourcePath: path_1.default.join(docsPath, "AI", "default", "MEMORY.md"),
94
+ copyPath: path_1.default.join(projectRoot, "memory", "MEMORY.md"),
95
+ aiLinkPath: path_1.default.join(aiPath, "MEMORY.md"),
96
+ aiLinkTarget: path_1.default.relative(aiPath, path_1.default.join(projectRoot, "memory", "MEMORY.md")),
97
+ },
98
+ ];
99
+ }
100
+ function tryLstat(filePath) {
101
+ try {
102
+ return fs_1.default.lstatSync(filePath);
103
+ }
104
+ catch (error) {
105
+ if (error.code === "ENOENT") {
106
+ return null;
107
+ }
108
+ throw error;
109
+ }
110
+ }
111
+ function isMissingOrEmptyFile(filePath) {
112
+ const stat = tryLstat(filePath);
113
+ if (!stat) {
114
+ return true;
115
+ }
116
+ return stat.isFile() && stat.size === 0;
117
+ }
118
+ function validateInitInstructionTargets(docsPath, instructionFiles) {
119
+ const projectRoot = path_1.default.dirname(docsPath);
120
+ const memoryPath = path_1.default.join(projectRoot, "memory");
121
+ if (fs_1.default.existsSync(memoryPath) && !fs_1.default.lstatSync(memoryPath).isDirectory()) {
122
+ console.error(`\nError: Cannot create memory/MEMORY.md because memory is not a directory: ${memoryPath}\n`);
123
+ process.exit(1);
124
+ }
125
+ for (const { copyPath } of instructionFiles) {
126
+ if (!isMissingOrEmptyFile(copyPath)) {
127
+ console.error(`\nError: Cannot initialize because ${path_1.default.relative(projectRoot, copyPath)} already exists and is not empty.\n` +
128
+ ` Move it, empty it, or choose another project root before running the initializer.\n`);
129
+ process.exit(1);
130
+ }
131
+ }
132
+ }
133
+ function createInitInstructionFiles(instructionFiles) {
134
+ for (const { sourcePath, copyPath, aiLinkPath, aiLinkTarget } of instructionFiles) {
135
+ fs_1.default.mkdirSync(path_1.default.dirname(copyPath), { recursive: true });
136
+ if (tryLstat(copyPath)) {
137
+ fs_1.default.unlinkSync(copyPath);
138
+ }
139
+ fs_1.default.copyFileSync(sourcePath, copyPath);
140
+ if (tryLstat(aiLinkPath)) {
141
+ fs_1.default.unlinkSync(aiLinkPath);
142
+ }
143
+ fs_1.default.symlinkSync(aiLinkTarget, aiLinkPath, "file");
144
+ }
145
+ }
146
+ function removeStarterDefaults(docsPath) {
147
+ fs_1.default.rmSync(path_1.default.join(docsPath, "AI", "default"), { recursive: true, force: true });
148
+ }
149
+ async function runInitWizard(options) {
150
+ const rl = (0, promises_1.createInterface)({ input: process.stdin, output: process.stdout });
151
+ try {
152
+ const folderAnswer = await rl.question("Documentation folder to create / Dossier de documentation à créer: ");
153
+ const folder = folderAnswer.trim();
154
+ if (!folder) {
155
+ console.error("\nError: Documentation folder is required.\n");
156
+ process.exit(1);
157
+ }
158
+ validateRelativeFolder(folder);
159
+ const docsPath = path_1.default.resolve(process.cwd(), folder);
160
+ let shouldCreateDocsPath = false;
161
+ if (options.starterLanguage && !parseInitLanguage(options.starterLanguage)) {
162
+ console.error("\nError: Invalid init language. Expected en or fr.\n");
163
+ process.exit(1);
164
+ }
165
+ if (fs_1.default.existsSync(docsPath)) {
166
+ const stat = fs_1.default.statSync(docsPath);
167
+ if (!stat.isDirectory()) {
168
+ console.error(`\nError: Not a directory: ${docsPath}\n`);
169
+ process.exit(1);
170
+ }
171
+ const existing = fs_1.default.readdirSync(docsPath);
172
+ if (existing.length > 0) {
173
+ console.error(`\nError: Folder is not empty: ${docsPath}\n`);
174
+ process.exit(1);
175
+ }
176
+ }
177
+ else {
178
+ shouldCreateDocsPath = true;
179
+ }
180
+ validateInitInstructionTargets(docsPath, initInstructionFiles(docsPath));
181
+ let initLanguage = options.starterLanguage ? parseInitLanguage(options.starterLanguage) : null;
182
+ if (!initLanguage && !process.stdin.isTTY) {
183
+ initLanguage = "en";
184
+ }
185
+ while (!initLanguage) {
186
+ const answer = await rl.question("Choose starter language / Choisissez la langue du starter [en/fr] (en): ");
187
+ initLanguage = answer.trim() === "" ? "en" : parseInitLanguage(answer);
188
+ if (!initLanguage) {
189
+ console.log("Please answer en or fr.");
190
+ }
191
+ }
192
+ if (shouldCreateDocsPath) {
193
+ fs_1.default.mkdirSync(docsPath, { recursive: true });
194
+ }
195
+ scaffoldStarter(docsPath, initLanguage);
196
+ replaceDocsFolderPlaceholders(docsPath, docsFolderReference(docsPath));
197
+ const instructionFiles = initInstructionFiles(docsPath);
198
+ createInitInstructionFiles(instructionFiles);
199
+ removeStarterDefaults(docsPath);
200
+ const port = parseInt(options.port, 10);
201
+ if (isNaN(port) || port < 1 || port > 65535) {
202
+ console.error("\nError: Invalid port number\n");
203
+ process.exit(1);
204
+ }
205
+ await (0, server_1.startServer)({ docsPath, port, openBrowser: options.open ?? false });
206
+ }
207
+ finally {
208
+ rl.close();
209
+ }
210
+ }
211
+ program
212
+ .name("living-ai-documentation")
213
+ .description("Serve a local Markdown documentation viewer over HTTP on your machine.")
214
+ .version("1.0.0")
215
+ .argument("[folder]", "Relative path to an existing documentation folder. Omit it to start the interactive initializer.")
216
+ .option("--starter-language <language>", "Starter language for the interactive initializer: en or fr")
217
+ .option("-p, --port <number>", "HTTP port to listen on (1-65535)", "4321")
218
+ .option("-o, --open", "Open the viewer in the default browser after startup")
219
+ .addHelpText("after", `
220
+ Examples:
221
+ $ npx living-ai-documentation Create a new documentation project interactively
222
+ $ npx living-ai-documentation ./mydocs Serve existing docs at http://localhost:4321
223
+ $ npx living-ai-documentation ./mydocs -p 5000 -o Serve on port 5000 and open the browser
224
+
225
+ Notes:
226
+ - The folder argument must be a relative path. Absolute paths (/abs/...) and ~-expansion are rejected
227
+ so .living-doc.json can be checked into git and shared across machines.
228
+ - When no folder is provided, the initializer asks for the target folder and starter language.
229
+ - The initializer copies AGENTS.md, CLAUDE.md and memory/MEMORY.md to the parent
230
+ of the documentation folder, then exposes them in <folder>/AI/ through symbolic links.
231
+ If one already exists with content, initialization stops instead of overwriting it.
232
+ - Configuration is persisted to <folder>/.living-doc.json. Edit it via the admin panel at /admin.
233
+ `)
234
+ .action(async (folder, options) => {
235
+ if (!folder) {
236
+ await runInitWizard(options);
237
+ return;
238
+ }
239
+ validateRelativeFolder(folder);
240
+ const docsPath = path_1.default.resolve(process.cwd(), folder);
241
+ if (!fs_1.default.existsSync(docsPath)) {
242
+ console.error(`\nError: Folder not found: ${docsPath}\n`);
243
+ process.exit(1);
244
+ }
245
+ const stat = fs_1.default.statSync(docsPath);
246
+ if (!stat.isDirectory()) {
247
+ console.error(`\nError: Not a directory: ${docsPath}\n`);
248
+ process.exit(1);
249
+ }
250
+ const port = parseInt(options.port, 10);
251
+ if (isNaN(port) || port < 1 || port > 65535) {
252
+ console.error("\nError: Invalid port number\n");
253
+ process.exit(1);
254
+ }
255
+ await (0, server_1.startServer)({ docsPath, port, openBrowser: options.open ?? false });
256
+ });
257
+ program.parseAsync().catch((error) => {
258
+ const message = error instanceof Error ? error.message : String(error);
259
+ console.error(`\nError: ${message}\n`);
260
+ process.exit(1);
261
+ });
262
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../bin/cli.ts"],"names":[],"mappings":"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"}