@kenjura/ursa 0.87.1 → 0.88.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.
package/CHANGELOG.md CHANGED
@@ -1,737 +1,785 @@
1
- # 0.87.1
2
- 2026-06-15
3
-
4
- - nothing
5
-
6
- # 0.87.0
7
- 2026-06-11
8
-
9
- - Added support for definition lists in Markdown/MDX documents, allowing for structured term-definition pairs to be rendered as HTML definition lists (<dl>, <dt>, <dd>).
10
- - Added response headers for json files with the ursa and doc repo version numbers, so consumers can invalidate caches when a new version is deployed.
11
-
12
-
13
- ## Serve Revamp (Phases 0–1)
14
-
15
- `ursa serve` could miss cascading updates — stylesheet edits, static files in `meta/`, template changes, and any change saved while a rebuild was already running — forcing a restart with `--clean`. This release ships the first two phases of the rework; design, root-cause analysis, and remaining TODOs: [docs/changes/serve-logic.md](docs/changes/serve-logic.md).
16
-
17
- - **Serve-mode reliability fixes (Phase 0):**
18
- - Static assets in `meta/` (images, fonts, PDFs, media) are now watched; replacing one re-copies it to output and reloads clients, without a full rebuild. Previously these changes were invisible until restart.
19
- - Changes saved while a regeneration is in flight are queued and processed when the current pass finishes, instead of being dropped with "changes lost".
20
- - Every full-rebuild path now deletes `content-hashes.json` and `nav-cache.json` first, so a rebuild after a template/meta change actually regenerates unchanged articles instead of hash-skipping them and leaving stale HTML.
21
- - The dependency tracker is persisted to `.ursa/dependency-graph.json` and reloaded on warm start, so hash-skipped documents keep their invalidation edges. Single-file regeneration now registers dependencies too, and template edits are recognized under the `templates/{name}/index.html` folder structure a template edit on a warm start is now a selective rebuild of just the documents using that template.
22
- - **New incremental build engine (Phase 1):** `src/helper/build/graph.js` a fingerprinted dependency graph (Make/Shake-style) with dynamic dependency discovery (`ctx.read`/`ctx.exists`/`ctx.get`), lookup nodes so file *creation* invalidates, size+mtime fast-path fingerprinting with content-hash confirmation, early cutoff, topological demand-driven scheduling, failure isolation with retry, and versioned persistence to `.ursa/graph.json`. Fully unit-tested; the build/serve pipelines will be ported onto it in the next phases (2–4).
23
-
24
- # 0.86.0
25
- 2026-05-18
26
-
27
- - small CSS fix
28
-
29
- # 0.85.0
30
- 2026-05-15
31
-
32
- - deflists in MDX
33
-
34
-
35
- # 0.84.0
36
- 2026-05-08
37
-
38
- - Unified sticky headers are now standard
39
-
40
- # 0.83.0
41
- 2026-05-07
42
-
43
- - **New `--promote-changelog=<file.md>` option** for the `generate` and `serve` commands. When supplied, the named markdown (or .mdx) file is staged into the source root for the duration of the build, so it is rendered by the normal Ursa pipeline and ends up in the output root as a sibling of the main `index.html`. The staged copy is removed after the build completes (or when the serve process exits via SIGINT/SIGTERM). If a file with the same basename already exists in the source root, no staging is performed and a warning is logged.
44
- - **Search UI fix**: clicking a search suggestion (or selecting one with Enter) now hides the search results dropdown immediately. Previously the dropdown could remain visible when navigation did not trigger a fresh page load (e.g. same-page anchor links, or restoration from the browser's back/forward cache). Also added a `pageshow` listener that hides results when the page is restored from bfcache.
45
- - **Search UI fully collapses after navigation**: clicking a search suggestion (in either the inline search dropdown or the search widget panel) now also closes the search widget panel and clears the search input, mirroring the effect of clicking the search icon a second time. The input is also cleared when the page is restored from the browser's back/forward cache.
46
- # 0.82.0
47
- 2026-05-06
48
-
49
- - **Frontmatter table is now opt-in**: The HTML frontmatter table that was previously injected into every Markdown/MDX document after the first H1 is now only rendered when the document's frontmatter sets `render-frontmatter: true` (boolean `true` or string `"true"`). Documents without the flag (or with it set to `false`) no longer have the table injected. The `render-frontmatter` key itself is excluded from the rendered table.
50
-
51
- # 0.81.4
52
- 2026-05-04
53
-
54
- - bug fix: directory index html files were never being written...impossibly, but there it is
55
-
56
- # 0.81.3
57
- 2026-04-14
58
-
59
- - bug fix: When script.js changes in serve mode, the bundle cache wasn't being cleared, so documents kept using stale bundles.
60
- - Added clearScriptCache() and clearStyleCache() functions in generate.js
61
- - Updated serve.js to call these functions when CSS/JS files change
62
-
63
-
64
- # 0.81.2
65
- 2026-03-28
66
-
67
- - MDX hydration: MDX documents now support hydration of embedded React components, allowing for interactive content within static pages.
68
-
69
- - **Fixed Recent Activity tracking**: The Recent Activity widget now properly tracks when document content actually changed, rather than relying on file system modification times (mtime).
70
- - Previously, Recent Activity used filesystem mtime, which doesn't work correctly after git clone (git doesn't preserve timestamps) or when all files are built simultaneously.
71
- - Now, content change timestamps are stored in `.ursa.json` (in the source directory), which:
72
- - Survives `--clean` builds (unlike the `.ursa/` cache folder)
73
- - Can be committed to git to preserve wiki history across clones
74
- - Falls back to file mtime for files that haven't been tracked yet (backward compatibility)
75
- - Both full builds and single-file regeneration (serve/dev mode) now update content timestamps when content actually changes (detected by hash comparison).
76
-
77
- # 0.80.1
78
- 2026-02-16
79
-
80
- - Fixed package.json issue
81
-
82
- # 0.80.0
83
- 2026-02-16
84
-
85
- - Added remark extensions to ensure MDX has the same extended markdown features as regular markdown (e.g. footnotes, definition lists, etc.)
86
-
87
- # 0.79.0
88
- 2026-02-14
89
-
90
- - Menu fixes:
91
- - Zero-item submenus will no longer be hidden if they have subfolders with one+ item
92
- - Bug fix for missing menu items
93
- - Level 2+ menus now have overflow:scroll (vertical only)
94
-
95
- # 0.78.0
96
- 2026-02-13
97
-
98
- - added release-it
99
- - --clean now fully deletes the .ursa cache folder and clears the output directory before generation, ensuring a completely fresh build without any stale files. Previously, --clean only ignored the cache but left existing output files in place, which could cause issues with stale auto-generated indexes and other files blocking new generation. This change provides a more robust clean build experience.
100
-
101
- # 0.77.0
102
- 2026-02-13
103
-
104
- QOL:
105
- - When 'serve' encounters an occupied port 8080, prompt the user to find an available port instead of just exiting with an error. Will check open ports and find the closest port to 8080, then ask the user if they want to use it.
106
-
107
- Meta cleanup:
108
- - Templates should have their own folder, including default
109
- - All static files for a template should be in the template's folder, and probably in the right subfolder (e.g. public/default.css should be in templates/default/public/default.css or something like that).
110
- - Template filenames should be templates/{templateName}/index.html
111
- - Ursa should throw a warning if it finds orphaned static files in meta that aren't referenced by a template
112
-
113
- Static assets revamp:
114
- - Revamped the building of static assets (stylesheets and scripts). The new logic is:
115
- - All meta scripts and stylesheets should be bundled together into a single CSS file and a single JS file for the entire site. This applies to build mode; in dev mode, they are served individually for easier debugging and regeneration.
116
- - Bundle-able document files (style.css, script.js, menu.md) will be bundled together on a per-folder basis. Each document will include the bundles from its own folder and all parent folders (where they exist).
117
-
118
- Regeneration revamp:
119
- - Existing logic:
120
- - On first generation, save a cache of document output given some sort of hash of the source file and metadata (e.g. mtime, size, etc.)
121
- - All static files (meta and document) should include a datetime or hash-based cache-buster in their query strings / filenames, so they can be invalidated as needed
122
- - On subsequent generations, if the source file's hash is unchanged, skip regeneration and reuse the existing output file. (Note: this doesn't handle cases where the statis files changed and the document didn't; see below)
123
- - Push a notification to the client when a file is regenerated, so the client can update the page if it's currently being viewed
124
- - New logic is as above, plus: (some of this is partially complete, but these are the complete requirements)
125
- - When any file being watched is changed, determine the list of affected files. For instance:
126
- - A normal document will obviously invalidate that exact document.
127
- - Special Ursa static files (menu.md, style.css, and script.js) are inherited by all documents in the current folder and all subfolders, so they will invalidate all documents in the current folder and all subfolders.
128
- - Meta static files:
129
- - A template file in meta will invalidate all documents that use that template.
130
- - A stylesheet or script file in meta will invalidate all documents that inherit from that meta (which is probably everything).
131
- - All other static files in the docroot (assuming they're linked at all by any document) should be invalidated thus:
132
- - Calculate a new hash for the static file
133
- - Find all documents that reference that static file
134
- - Regenerate the html (even if the source md/mdx/txt file is unchanged) for those documents to update the cache-busting query string for the static file reference
135
- - This should catch all the various edge cases that previously required restarting the server or doing a full regeneration.
136
- - Regeneration priority order:
137
- - When regeneration is triggered, check for connected WebSocket clients and get their current URL.
138
- - If their current URL is affected by the change (document, static asset, template, anything), prioritize the necessary documents and assets to serve that URL before all others, and when they are regenerated, send the push notification to reload.
139
- - After that, regenerate the rest of the affected documents in the background.
140
- - In cases of rapid changing of files, do the following:
141
- - Debounce all file system change events within a short time window (e.g. 500ms); wait for at least 500ms of no changes before starting regeneration. This helps in cases where a script or bot is making many changes to many files.
142
- - When a change is detected, before any complex processing, send a ping to WebSocket-connected clients that an update is in progress, but it isn't known yet if it will affect their page.
143
- - When it is determined that a change will affect the current page of a connected client, send another push to let the client know.
144
- - Handle the above two notifications in the UI thus:
145
- - When updates start, add a subtle loading indicator to the right of all left widgets, such as <Loader color="gray" />
146
- - If it turns out the update doesn't need a refresh, remove the indicator.
147
- - If it does need a refresh, change the indicator to a <Loader color="green" />.
148
- - When the hot refresh actually happens, the indicator shouldn't be there anymore.
149
- - Cache changes (under consideration):
150
- - Before the cache was implemented, every file change triggered a complete regeneration of the entire site. This was slow, obviously. First, an in-memory cache was added to speed up the regeneration of unchanged files. But since the watcher back then missed a lot of regeneration cases (such as all meta changes), killing 'serve' and restarting it was quite common. Thus, the cache was persisted to disk, so that even in the case of a full regeneration (such as after a restart), unchanged files would still be skipped. This has worked fairly well, but for the invalidation edge cases described above (already fixed).
151
- - However, considering that we now have a robust regeneration system that can handle all edge cases and push updates to the client, we may want to consider removing the cache entirely. The cache adds complexity and can sometimes get into a bad state, requiring manual deletion. With the new regeneration system, we could keep the cache in-memory, and rarely will the user need to kill 'serve' and restart just to get an update (ideally, never). In-memory cache is even faster than disk, so this might be a better experience overall.
152
- - Regeneration cases still unhandled:
153
- - User updates Ursa itself (e.g. npm update) while serve is active. I mean, this shouldn't be very common outside of Ursa devs, but's determine:
154
- - Does the current system actually catch the meta changes?
155
-
156
-
157
-
158
- Top Menu improvements:
159
- - When a submenu overflows the available viewport height, it should become scrollable instead of overflowing off the screen. This can be achieved with CSS by setting a max-height and overflow-y: auto on the submenu container.
160
-
161
- New Widgets:
162
- - Suggested Content
163
- - A new left-side widget that shows a list of suggested content based on the current page. Categories of suggested content:
164
- - Content you frequently view (uses localStorage to track page views and show most viewed content)
165
- - Future ideas:
166
- - LLM-guided suggestions based on frequently viewed content, suggested related documents you haven't viewed yet, etc.
167
-
168
- Bugs:
169
- - [x] When using menu.md with auto-generation, the top menu's Home href is "//index.html" instead of "/index.html". On localhost, this ends up working fine, but on https://realdomain.com, this loads https://index.html which obviously doesn't work. The current logic seems to prefer absolute URLs, so in this case, the url for home should be "/index.html" (not double slash).
170
- - [x] Site style.css is not present on auto-generated index pages
171
- - Regeneration issues:
172
- - Create a power, that power page now exists. But powers.json doesn't have it.
173
-
174
- # 0.76.0
175
- 2026-02-11
176
-
177
- - **New Feature: Recent Activity widget.** A new topbar widget shows the 10 most recently modified documents in the docroot, sorted by modification date (most recent first). The widget appears on the left side of the top nav (to the right of the home icon) and is open by default.
178
- - Recent activity data is collected during the generate phase by stat-ing each article file, then written to `public/recent-activity.json`.
179
- - In serve/dev mode, the recent activity list is built during background cache initialization and updated live when article files are changed.
180
- - The single-file regeneration path (`regenerateSingleFile`) also updates the recent activity JSON incrementally.
181
- - **Widget system improvements:**
182
- - All widgets now have a close (✕) button in the upper-right corner of their panel header. Clicking it closes the widget and deselects the corresponding icon in the top bar.
183
- - Widget open/closed state is now persisted in localStorage. Widgets that were open will remain open after a page reload, and widgets that were closed will remain closed. Widgets with no saved state fall back to their default (Recent Activity defaults to open; others default to closed).
184
- - The widget system now supports both left-side and right-side widget panels, which operate independently (one widget per side can be open at a time).
185
-
186
- # 0.75.0
187
- 2026-02-10
188
-
189
- - Top Menu changes: the top menu is now the default first-level navigation. Top-left nav is either root, or 'hamburger' on smaller screens.
190
- - Right column is now a standardized widget zone, with TOC, Search, and Profile widgets implemented.
191
- - Default header: documents without an initial H1 will now have their title rendered as an H1 header at the top of the article. Index/home pages will default to the parent folder name if not overridden.
192
- - Breadcrumbs: added breadcrumbs to the top of each article for easier navigation and context
193
-
194
- # 0.74.0
195
- 2026-02-08
196
-
197
- - added a feature to skip preview generation and swapping on a per-image basis. You can use the data-no-preview tag in html, and the ?no-preview query parameter in markdown or wikitext images.
198
- - when building automenus and autoindex pages, folders with no md/mdx/txt/html documents anywhere in their tree will not be shown.
199
-
200
- # 0.73.0
201
- 2026-02-07
202
-
203
- - fixed build pipeline blocker
204
-
205
- # 0.72.0
206
- 2026-02-07
207
-
208
- - MDX support: Ursa can now process .mdx files with embedded JSX components
209
- - MDX files are parsed and rendered to HTML with React components
210
- - Custom components can be imported and used within MDX content
211
- - MDX documents are fully integrated with Ursa's build and serve processes, including hot reloading in dev mode
212
- - This allows for rich interactive content while still benefiting from Ursa's static site generation features
213
-
214
- # 0.71.0
215
- 2026-02-05
216
-
217
- - 'Dev mode': new mode similar to serve, but only generates documents on-demand to save time.
218
- - When running `ursa dev`, the server starts immediately without a full build
219
- - Documents are generated on-the-fly when requested, with caching for subsequent requests
220
- - Ideal for development with large sites where full builds are slow
221
- - Still supports hot reloading and file watching for dynamic updates
222
- - Custom menus can now include auto-generated menus in addition to custom content
223
- - Custom menus are displayed on the top bar instead of the side
224
-
225
- # 0.70.0
226
- 2026-02-04
227
-
228
- - **Navigation Cache**: Dramatically improved navigation build time
229
- - Navigation structure cached in `.ursa/nav-cache.json`
230
- - Cache validated by file list hash + metadata file stats (index.md, config.json)
231
- - Parallel stat operations for faster cache validation
232
- - Result: Navigation build drops from ~9s to ~50ms on cached runs (99% improvement)
233
-
234
- # 0.69.0
235
- 2026-02-04
236
-
237
- - **Image Processing Performance**: Dramatically improved image processing speed
238
- - Persistent image cache: images are only re-processed when source file changes (mtime/size check)
239
- - Parallel processing: 8 images processed concurrently instead of sequentially
240
- - Smart preview skipping: images smaller than 800x800 skip preview generation (already small enough)
241
- - Result: Image processing drops from ~23s to ~16ms on cached runs (99.9% improvement)
242
-
243
- # 0.68.0
244
- 2026-02-04
245
-
246
- - **Build Performance Profiling**: Added comprehensive profiling to identify performance bottlenecks
247
- - Each build phase is now timed with millisecond precision
248
- - Visual bar chart report shows percentage of total build time per phase
249
- - Phases tracked: Scan source files, Filter & classify, Build navigation, Load cache, Copy meta files, Process images, Process articles, Write search index, Write menu data, Process directories, Process static files, Auto-index generation, Finalization
250
- - Report displayed at end of each build for performance analysis
251
-
252
- # 0.67.0
253
- 2026-02-04
254
-
255
- - All images referenced in whitelisted documents should be processed and copied, even if the images themselves are not in the whitelist
256
-
257
- # 0.66.0
258
- 2026-02-04
259
-
260
- - Links to a markdown file in source will now render as a link to the corresponding .html file even if the target file does not exist yet
261
- - Relative URLs in raw HTML elements (img src, video src, etc.) embedded in markdown files are now resolved relative to the document's location
262
- - Relative URLs in inline style `url()` values (e.g., `background-image: url('./img/foo.webp')`) are now resolved relative to the document's location
263
-
264
- # 0.65.0
265
- 2026-02-01
266
-
267
- - Fixed issue where images wrapped in an anchor tag were incorrectly given a click handler to open in a new tab
268
-
269
- # 0.64.0
270
- 2026-01-31
271
-
272
- - Handles scenario where a new image is added while serving (previously the image wouldn't show without a full restart)
273
- - New images are now processed on-the-fly when detected in serve mode
274
- - Image previews are generated and copied to output automatically
275
- - HTML is updated to use preview images without needing a full rebuild
276
-
277
- # 0.63.0
278
- 2026-01-31
279
-
280
- - Images inside an anchor tag will no longer have a click handler added to open the image in a new tab
281
-
282
-
283
- # 0.62.2
284
- 2026-01-29
285
-
286
- - Fixed CI issue with pnpm using npm-specific syntax
287
-
288
- # 0.62.1
289
- 2026-01-29
290
-
291
- - CI now uses pnpm to avoid redundant package managers
292
-
293
- # 0.62.0
294
- 2026-01-29
295
-
296
- - **Enhanced Auto-Index**: Index documents can now configure auto-index generation via frontmatter
297
- - `generate-auto-index: true` - Include an auto-generated index listing in the page
298
- - `auto-index-depth: N` - Control recursion depth (1 = current folder, 2 = current + subfolders, etc.)
299
- - `auto-index-position: top|bottom` - Insert the auto-index before or after the document content
300
-
301
- - **Faster Serve Mode**: The `serve` command now uses deferred image processing for significantly faster startup
302
- - HTML files are generated immediately with original image paths
303
- - Image preview generation runs in the background after HTML is ready
304
- - Site is browsable within seconds instead of waiting for full image processing
305
- - Images will display as originals until preview generation completes (then show optimized WebP previews)
306
- - Added hot reloading for regeneration
307
-
308
- - **Bug Fixes**:
309
- - Fixed issue where style.css changes were not reflected until server restart in `serve` mode
310
- - Fixed issue where root-level auto-index had incorrect HREFs
311
- - Fixed issue where re-generating an index document with `generate-auto-index:true` did not include the auto-index until server restart
312
- - Fixed issue where auto-indexer was rendering 'img' folders
313
-
314
- # 0.61.1
315
- 2026-01-14
316
-
317
- - Fix: package-lock.json version mismatch
318
-
319
- # 0.61.0
320
- 2026-01-14
321
-
322
- - Image Handling
323
- - [x] When an image tag is encountered, and the image is found in the static assets:
324
- - [x] Process the image to a preview size (max width/height == article width (50rem) or px equivalent), and convert to webp with reasonable compression. Copy the original image as well as the preview.
325
- - [x] Generate the HTML img tag as is currently done, but:
326
- - [x] Use the preview image as the src
327
- - [x] Use the original image as the data-fullsrc attribute
328
- - [x] On click, open the original image in a new tab
329
-
330
- # 0.60.0
331
- 2026-01-03
332
-
333
- - added `menu-label` frontmatter field to override default menu labels
334
- - added `menu-sort-as` frontmatter field for custom sort ordering
335
- - metadata-only index.md files now trigger auto-index generation
336
- - index files sorted to top of menu panes with distinct styling
337
- - fixed menu column vertical scrolling
338
- - excluded Ursa-internal fields from frontmatter table display
339
-
340
- # 0.59.0
341
- 2026-01-01
342
-
343
- - added frontmatter rendering
344
-
345
- # 0.58.0
346
- 2025-12-26
347
-
348
- - new menu UI with 2-pane horizontal layout
349
-
350
- # 0.57.0
351
- 2025-12-26
352
-
353
- - added full-text indexing and search using lunr.js
354
- - all links in generated html will be full links with extensions (e.g. /folder/page.html)
355
-
356
- # 0.56.0
357
- 2025-12-23
358
-
359
- - restored metadata to directory index JSON files
360
-
361
- # 0.55.0
362
- 2025-12-21
363
-
364
- - custom menus (menu.md|txt) override the automenu when present
365
-
366
- # 0.54.0
367
- 2025-12-21
368
-
369
- - added cache-busting timestamps to static files
370
- - cleaned up generate.js by moving helper functions to separate files
371
-
372
-
373
- # 0.53.0
374
- 2025-12-21
375
-
376
- ### Menu Size Optimization
377
- - **External Menu JSON**: Menu data is now stored in `/public/menu-data.json` instead of being embedded in every HTML file. This dramatically reduces HTML file sizes for sites with large folder structures (e.g., from 2-3MB per file down to ~50KB).
378
- - **Async Menu Loading**: Menu data is fetched asynchronously after page render, showing a "Loading menu..." indicator until ready.
379
- - **Debug Fields Removed**: Menu JSON no longer includes debug/inactive fields, reducing JSON size further.
380
- - **Gzip Compression**: Development server now uses gzip compression for all responses, significantly reducing transfer size for JSON and HTML files.
381
-
382
- # 0.52.0
383
- 2025-12-21
384
-
385
- - Fixed search results not displaying correctly when no matches are found
386
-
387
- # 0.51.0
388
- 2025-12-21
389
-
390
- - Existing .html files are no longer overwritten by generated documents.
391
-
392
- # 0.50.0
393
- 2025-12-21
394
-
395
- ### Performance Optimizations
396
- - **CSS Path Caching**: Implemented caching for `findStyleCss()` lookups during generation. Reduces redundant filesystem walks for documents in the same directory tree.
397
- - **Template Replacement Optimization**: Changed from 8 sequential `string.replace()` calls to a single regex pass, reducing intermediate string allocations.
398
- - **Wikitext Regex Pre-compilation**: Pre-compiled ~40 regex patterns at module load time instead of compiling on every `wikiToHtml()` call.
399
-
400
- ### New Features
401
- - **Static File Watch**: `ursa serve` now watches for new/changed static files (images, fonts, PDFs, etc.) and automatically copies them to output without requiring a full rebuild.
402
-
403
- ### Bug Fixes
404
- - **Menu Folder Expansion**: Fixed issue where navigating to `/folder` wouldn't auto-expand the menu, but `/folder/index.html` would. Both now behave consistently by normalizing trailing slashes in URL comparison.
405
-
406
-
407
- # 0.49.0
408
- 2025-12-20
409
-
410
- - Fixed more instances of false inactive links, this time in wikitext files (.txt)
411
- - **Auto-Index Style Fix**: Auto-generated index pages now correctly inherit `style.css` from parent folders, just like normal documents
412
- - **Clean Build Fix**: The `--clean` flag now properly clears the output directory before generation. Previously it only ignored the hash cache, which could leave stale files (like old auto-generated indexes) that would block new generation.
413
-
414
-
415
- # 0.48.0
416
- 2025-12-20
417
-
418
- - **External CSS**: CSS files are now externally linked via `<link>` tags instead of being embedded in each HTML page. This significantly reduces HTML file sizes and improves browser caching.
419
- - **Fast CSS Updates**: CSS file changes in watch mode now just copy the file to output (~1ms) instead of triggering a full rebuild
420
- - **Fast Single-File Regeneration**: Article changes in watch mode use a new fast-path that regenerates only the changed file (~50-100ms) instead of scanning all source files
421
- - **Clickable Folder Links**: All folders in the navigation menu are now clickable links (auto-index ensures every folder has an index.html)
422
- - **Menu Collapse Fix**: Fixed issue where clicking the caret on a folder containing the current page wouldn't collapse it
423
- - **URL Encoding Fix**: Fixed menu not highlighting current page when URLs contain spaces or special characters
424
- - **Link Validation Fix**: Links to folders are no longer incorrectly marked as inactive (folders now included in valid paths since auto-index generates index.html for all)
425
- - **WikiText Link Fix**: Fixed wikitext links (in .txt files) being incorrectly marked as inactive. Link validation is now handled centrally by the link validator after HTML generation.
426
- - **Folder/Index Link Fix**: Links to folders containing a `(foldername).md` file (instead of `index.md`) are now correctly recognized as valid
427
-
428
- # 0.47.0
429
- 2025-12-20
430
-
431
- - Improved handling of trailing slashes in URLs to ensure consistency across all links and resources
432
-
433
- # 0.46.0
434
- 2025-12-20
435
-
436
- - Normalized handling of trailing slashes in URLs
437
-
438
- # 0.45.0
439
- 2025-12-20
440
-
441
- - Added --exclude flag to ignore specified files or directories during generation
442
- - Improved performance of the serve command with optimized file watching
443
- - Automatically generating index.html for directories without an index file
444
-
445
- # 0.44.0
446
- 2025-12-16
447
-
448
- - Added 'sections' metadata property with hierarchical section structure
449
-
450
- # 0.43.0
451
- 2025-12-14
452
-
453
- - Added buildId and .ursa.json
454
- - Added full datetime to footer
455
- - Added commit hash to footer as comment
456
-
457
- # 0.42.0
458
- 2025-12-14
459
-
460
- - Automenu will now remove dashes from file names
461
-
462
- # 0.41.0
463
- 2025-12-13
464
-
465
- - Fixed footer bug
466
-
467
- # 0.40.0
468
- 2025-12-13
469
-
470
- - Added footer
471
-
472
- # 0.39.0
473
- 2025-12-13
474
-
475
- - Updated to node 24.5 to satisfy npm Trusted Publishing
476
- - Refactored Github Actions
477
- - Added CONTRIBUTING.md
478
-
479
- # 0.38.0
480
- 2025-12-13
481
-
482
- - Updated Github Actions workflow to use OIDC for authentication
483
-
484
- # 0.37.0
485
- 2025-12-13
486
-
487
- - Added Github Actions workflow for CI/CD (npm publish)
488
-
489
- # 0.36.0
490
- 2025-12-13
491
-
492
- - Links to a valid .md file in source will now render as a link to the corresponding .html file (and show as an active link)
493
-
494
- # 0.35.0
495
- 2025-12-11
496
-
497
- - Fixed issue where directory indices were empty
498
-
499
- # 0.34.0
500
- 2025-12-11
501
-
502
- - Added config.json with folder-specific settings for label, icon, and visibility
503
- - Root-level config.json can specify open menu items
504
-
505
- # 0.33
506
- 2025-12-10
507
-
508
- - Fixed the broke-ass menu
509
-
510
- # 0.32
511
- 2025-12-10
512
-
513
- - Using .ursa folder in source directory for content hash cache
514
- - Added --clean flag to ignore cache and regenerate all files
515
- - Set up npm config for public package publishing
516
-
517
- # 0.31
518
- 2025-12-09
519
-
520
- - Added URL property to JSON directory indices
521
- - Ensured directory indices are recursive
522
-
523
- # 0.30
524
- 2025-12-07
525
-
526
- - Fixed broken link detection to correctly identify broken internal links
527
-
528
- # 0.29.0
529
- 2025-12-07
530
-
531
- - New nav-main style, two-levels only (but supports any depth), looks way better
532
-
533
- # 0.28.0
534
- 2025-12-07
535
-
536
- - Added broken link detection and styles
537
- - Fixed hole in "serve" logic that didn't regenerate style.css
538
-
539
- # 0.27.0
540
- 2025-12-07
541
-
542
- - Capitalizing nav-main labels
543
-
544
- # 0.26.0
545
- 2025-12-06
546
- - Fixed global nav styles in desktop
547
- - Updated main nav style to match TOC
548
-
549
- # 0.25.0
550
-
551
- 2025-12-06
552
-
553
- - Enhanced mobile navigation with hamburger toggle that changes to X when menu is open
554
- - Improved button accessibility with dynamic aria-label updates
555
-
556
- # 0.24.0
557
-
558
- 2025-12-06
559
-
560
- - Added support for index files in folder links
561
- - Folders with index.md/txt/yml now link to /folder/index.html
562
- - Folders without index files render as non-clickable text
563
-
564
- # 0.23.0
565
-
566
- 2025-12-04
567
-
568
- - Implemented incremental build support with content hashing
569
- - Source file changes now only regenerate modified files
570
- - Meta file changes still trigger full rebuild
571
- - Added .content-hashes.json cache for tracking file changes
572
-
573
- # 0.22.0
574
-
575
- 2025-12-04
576
-
577
- - New Notion-style nav-main sidebar design
578
- - Added folder/document icons with custom icon support
579
- - Collapsible menu items with expand arrows
580
- - Responsive flexbox layout for nav-global
581
-
582
- # 0.21.0
583
-
584
- 2025-12-01
585
-
586
- - Enhanced error handling for template retrieval
587
- - Better error messages when templates are not found
588
-
589
- # 0.20.0
590
-
591
- 2025-12-01
592
-
593
- - Added fault tolerance to generate command
594
- - Individual file errors no longer stop entire build
595
- - Errors collected and written to _errors.log
596
-
597
- # 0.19.0
598
-
599
- 2025-11-21
600
-
601
- - Fixed YAML parsing issues with horizontal rules being mistaken for front matter
602
- - Improved regex to require closing --- on its own line
603
-
604
- # 0.18.0
605
-
606
- 2025-11-21
607
-
608
- - Fixed errors with wikitext rendering
609
- - Better handling of undefined args.db
610
-
611
- # 0.17.0
612
-
613
- 2025-10-23
614
-
615
- - Added Table of Contents (TOC) generation
616
- - Smooth scrolling to headings with offset adjustment
617
- - Active heading tracking in TOC
618
-
619
- # 0.16.0
620
-
621
- 2025-10-22
622
-
623
- - AI-implemented search feature with typeahead
624
- - Search index built from all articles during generation
625
-
626
- # 0.15.0
627
-
628
- 2025-10-22
629
-
630
- - Improved mobile responsiveness
631
- - Better media query breakpoint (800px)
632
- - Enhanced h1 styling and article width for mobile
633
-
634
- # 0.14.0
635
-
636
- 2025-10-22
637
-
638
- - Fixed sticky header generation
639
- - Enhanced sticky header functionality
640
- - Added responsive navigation styles
641
-
642
- # 0.13.0
643
-
644
- 2025-10-07
645
-
646
- - Added whitelist feature for selective file generation
647
- - Added sectionify script for content organization
648
- - Fixed bugs in node-watch for file monitoring
649
- - Working sticky headers implementation
650
-
651
- # 0.12.0
652
-
653
- 2025-10-06
654
-
655
- - Added debug CLI mode
656
- - Fixed embedded style issues
657
- - Added site navigation
658
- - Total rewrite of base CSS (article and topnav)
659
- - Added custom CSS support (disabled by default)
660
-
661
- # 0.11.0
662
-
663
- 2025-07-28
664
-
665
- - added CLI commands (e.g. "ursa src" and "ursa serve src")
666
-
667
- # 0.10.0
668
-
669
- 2024-03-13
670
-
671
- - Will no longer write an autoindex when index document already exists
672
-
673
- # 0.9.0
674
-
675
- 2024-02-10
676
-
677
- - Removed spammy debug data from json
678
-
679
- # 0.8.0
680
-
681
- 2023-12-31
682
-
683
- - Fixed recursive-readdir to actually return directories, not just files
684
-
685
- # 0.7.0
686
-
687
- 2023-08-01
688
-
689
- - removed all non-public modules
690
-
691
- # 0.6.0
692
-
693
- 2023-08-01
694
-
695
- - removed some dependencies that required private auth for npm install
696
-
697
- # 0.5.0
698
-
699
- 2023-05-08
700
-
701
- - added INCLUDE_FILTER env var
702
-
703
- # 0.4.2
704
-
705
- 2023-03-01
706
-
707
- - bug fixes
708
-
709
- # 0.4.0
710
-
711
- 2023-03-31
712
-
713
- - Now a library
714
-
715
- # 0.3.0
716
-
717
- 2022-10-17
718
-
719
- - Using express instead of http/node-static for serve
720
- - Serve now waits for generation to finish
721
- - Formatted files using prettier
722
-
723
- # 0.2.0
724
-
725
- 2022-03-30
726
-
727
- - Added serve command
728
- - Workaround for node-static broken npm package
729
- - Added source static files and menu
730
- - Lots of default styling (not that meta should be in there at all)
731
- - Added TODO
732
-
733
- # 0.1.0
734
-
735
- 2022-03-30
736
-
737
- - Initial POC
1
+ # 0.88.0
2
+ 2026-08-19
3
+
4
+ `ursa serve` gains `--strict-port`, and stops prompting when nobody can answer.
5
+
6
+ Serving a wiki is increasingly one process among several — a `pnpm dev` that starts an app, an API and a docs site in parallel. The interactive "Port 8080 is already in use. Use port 8082 instead? (Y/n)" fallback is wrong in that setting twice over: sibling processes share stdin, so the question either hangs the whole dev command or eats a keystroke meant for something else; and a different port is not a good outcome anyway, because whatever embeds the wiki — an iframe, a proxy, a link — was configured with the port that was asked for, so moving silently produces a broken embed with no error anywhere.
7
+
8
+ - **`--strict-port`** fails with a clear message instead of falling back. This is what a dev script wants.
9
+ - **Without it, a non-TTY stdin no longer prompts.** It picks the fallback port and says so loudly, including that anything pointed at the original port must be updated. Interactive terminals are unchanged.
10
+ - `resolvePort(port, { strict, interactive })` is the programmatic form; `interactive` defaults to `process.stdin.isTTY`.
11
+
12
+ The error for an occupied WebSocket port now says that is what happened — hot reload listens on `port + 1`, and being told "port 8081 is in use" when you asked for 8080 reads as a bug in ursa.
13
+
14
+ # 0.87.5
15
+ 2026-08-19
16
+
17
+ Fixed a build that silently produced nothing when the docroot lived under a dot-directory — a git worktree inside `.claude/worktrees/`, anything under `~/.config` or `~/.local`. Two independent places tested hidden-folder patterns against the **absolute** path rather than the path relative to the docroot, so the docroot's own ancestry marked the entire site hidden.
18
+
19
+ The symptom was unhelpful in both halves. `generate` classified **0 articles** out of 31 scanned files and carried on, so a build could report success and write an empty site; and `getAutomenu` then died on `Cannot read properties of null (reading 'children')`, because `directory-tree` had excluded the root and returned `null` — a stack trace pointing at menu construction for a problem that was neither about menus nor about that file.
20
+
21
+ - **`helper/hiddenPaths.js` (new)** `toSourceRelative()` and `isHiddenOrSystemPath()`, the single place that decides what "hidden" means. Judged relative to the docroot, always separator-prefixed so a genuinely hidden top-level folder (`<source>/.drafts`) still matches.
22
+ - **`jobs/generate.js` and `dev.js`** now route every hidden/system test through it, instead of matching absolute paths in seven places.
23
+ - **`helper/automenu.js`** walks the tree first and prunes after, rather than handing `directory-tree` an absolute-path `exclude` that can reject the root itself. A docroot containing `node_modules` is now walked before being discarded, which is the price of being right about every ordinary path. Also raises a legible error if the docroot genuinely cannot be read, rather than passing `null` downstream.
24
+
25
+ Output for a docroot on an ordinary path is byte-for-byte unchanged.
26
+
27
+ # 0.87.4
28
+ 2026-08-13
29
+
30
+ Fixed three ways an index page could go permanently stale on warm builds, so that adding, renaming, or deleting content stopped appearing in any listing that should have contained it. Symptom: a brand-new folder rendered its own page correctly, but nothing linked to it — the root landing page, the parent folder's listing, and the parent folder's generated `index.html` all kept describing the tree as it looked the first time they were written, sometimes months earlier.
31
+
32
+ - **Documents with `generate-auto-index: true` are now always regenerated.** Their output is a listing of the source tree, so it depends on which folders and files exist — not just on the document's own text, which is all `needsRegeneration()` hashes. Adding a folder elsewhere in the tree left the hash untouched, so the document was skipped forever and its embedded index never grew. Only a handful of documents opt in, so they are simply rebuilt every pass.
33
+ - **Generated directory listings (`<dir>.html`) are no longer write-once.** The old guard skipped the write whenever the file already existed, which froze the listing at its first build. It now rewrites every pass, guarded instead by ownership: a document that renders to the same path — an article named after its own folder (`settings/starwars/people.md` alongside `settings/starwars/`), or a hand-written `.html` in the source tree — keeps the path, and the listing is not written there at all. That collision is what the old existence check was incidentally protecting against.
34
+ - **Auto-generated folder `index.html` files are no longer write-once**, for the same reason and with the same reasoning: folders with a source index document and hand-written source HTML were already excluded from that code path, and alternates (`_index.html`, `home.html`, `<foldername>.html`) are re-promoted on every pass, so nothing authoritative is at risk.
35
+
36
+ Cost of rebuilding these listings on every warm build, measured on a 465-directory site: 3.01s → 3.24s total.
37
+
38
+ # 0.87.3
39
+ 2026-08-09
40
+
41
+ - Fixed silent incomplete builds caused by hash-skipping (the TODO logged in 0.87.2). `needsRegeneration()` compared only the source content hash, but the hash cache lives in the *source* tree (`<source>/.ursa/content-hashes.json`) and is therefore shared by every output directory built from that source. A build to one output dir recorded hashes that made a later build to a different output dir skip those documents entirely — emitting auto-index entries linking to `.html` files that were never written. Deleting or partially losing `output/` had the same effect. Both the article and static-file paths now also require the expected output files to exist before skipping.
42
+
43
+ # 0.87.2
44
+ 2026-08-09
45
+
46
+ - Fixed a crash when `ursa serve` fell back to an alternative port. The fallback search only checked whether the HTTP port was free, so it could offer a port whose WebSocket port (`port + 1`) was still occupied — e.g. offering 8079 when 8080/8081 were both taken, then dying with `EADDRINUSE` on the hot-reload server. Port selection now requires both ports of the pair to be available.
47
+ - TODO (fixed in 0.87.3): Hash-skipping in `generate()` assumes the corresponding output files (`.html`/`.json`/`.xml`) still exist on disk. If `output/` is deleted (or partially lost) while `<source>/.ursa/content-hashes.json` survives, a normal (non-clean) build silently produces incomplete output — e.g. the root `index.html` is never written because `docs/index.md` is hash-skipped. Fix: make `needsRegeneration()` also force a rebuild when the expected output file is missing.
48
+
49
+ # 0.87.1
50
+ 2026-06-15
51
+
52
+ - nothing
53
+
54
+ # 0.87.0
55
+ 2026-06-11
56
+
57
+ - Added support for definition lists in Markdown/MDX documents, allowing for structured term-definition pairs to be rendered as HTML definition lists (<dl>, <dt>, <dd>).
58
+ - Added response headers for json files with the ursa and doc repo version numbers, so consumers can invalidate caches when a new version is deployed.
59
+
60
+
61
+ ## Serve Revamp (Phases 0–1)
62
+
63
+ `ursa serve` could miss cascading updates — stylesheet edits, static files in `meta/`, template changes, and any change saved while a rebuild was already running — forcing a restart with `--clean`. This release ships the first two phases of the rework; design, root-cause analysis, and remaining TODOs: [docs/changes/serve-logic.md](docs/changes/serve-logic.md).
64
+
65
+ - **Serve-mode reliability fixes (Phase 0):**
66
+ - Static assets in `meta/` (images, fonts, PDFs, media) are now watched; replacing one re-copies it to output and reloads clients, without a full rebuild. Previously these changes were invisible until restart.
67
+ - Changes saved while a regeneration is in flight are queued and processed when the current pass finishes, instead of being dropped with "changes lost".
68
+ - Every full-rebuild path now deletes `content-hashes.json` and `nav-cache.json` first, so a rebuild after a template/meta change actually regenerates unchanged articles instead of hash-skipping them and leaving stale HTML.
69
+ - The dependency tracker is persisted to `.ursa/dependency-graph.json` and reloaded on warm start, so hash-skipped documents keep their invalidation edges. Single-file regeneration now registers dependencies too, and template edits are recognized under the `templates/{name}/index.html` folder structure — a template edit on a warm start is now a selective rebuild of just the documents using that template.
70
+ - **New incremental build engine (Phase 1):** `src/helper/build/graph.js` — a fingerprinted dependency graph (Make/Shake-style) with dynamic dependency discovery (`ctx.read`/`ctx.exists`/`ctx.get`), lookup nodes so file *creation* invalidates, size+mtime fast-path fingerprinting with content-hash confirmation, early cutoff, topological demand-driven scheduling, failure isolation with retry, and versioned persistence to `.ursa/graph.json`. Fully unit-tested; the build/serve pipelines will be ported onto it in the next phases (2–4).
71
+
72
+ # 0.86.0
73
+ 2026-05-18
74
+
75
+ - small CSS fix
76
+
77
+ # 0.85.0
78
+ 2026-05-15
79
+
80
+ - deflists in MDX
81
+
82
+
83
+ # 0.84.0
84
+ 2026-05-08
85
+
86
+ - Unified sticky headers are now standard
87
+
88
+ # 0.83.0
89
+ 2026-05-07
90
+
91
+ - **New `--promote-changelog=<file.md>` option** for the `generate` and `serve` commands. When supplied, the named markdown (or .mdx) file is staged into the source root for the duration of the build, so it is rendered by the normal Ursa pipeline and ends up in the output root as a sibling of the main `index.html`. The staged copy is removed after the build completes (or when the serve process exits via SIGINT/SIGTERM). If a file with the same basename already exists in the source root, no staging is performed and a warning is logged.
92
+ - **Search UI fix**: clicking a search suggestion (or selecting one with Enter) now hides the search results dropdown immediately. Previously the dropdown could remain visible when navigation did not trigger a fresh page load (e.g. same-page anchor links, or restoration from the browser's back/forward cache). Also added a `pageshow` listener that hides results when the page is restored from bfcache.
93
+ - **Search UI fully collapses after navigation**: clicking a search suggestion (in either the inline search dropdown or the search widget panel) now also closes the search widget panel and clears the search input, mirroring the effect of clicking the search icon a second time. The input is also cleared when the page is restored from the browser's back/forward cache.
94
+ # 0.82.0
95
+ 2026-05-06
96
+
97
+ - **Frontmatter table is now opt-in**: The HTML frontmatter table that was previously injected into every Markdown/MDX document after the first H1 is now only rendered when the document's frontmatter sets `render-frontmatter: true` (boolean `true` or string `"true"`). Documents without the flag (or with it set to `false`) no longer have the table injected. The `render-frontmatter` key itself is excluded from the rendered table.
98
+
99
+ # 0.81.4
100
+ 2026-05-04
101
+
102
+ - bug fix: directory index html files were never being written...impossibly, but there it is
103
+
104
+ # 0.81.3
105
+ 2026-04-14
106
+
107
+ - bug fix: When script.js changes in serve mode, the bundle cache wasn't being cleared, so documents kept using stale bundles.
108
+ - Added clearScriptCache() and clearStyleCache() functions in generate.js
109
+ - Updated serve.js to call these functions when CSS/JS files change
110
+
111
+
112
+ # 0.81.2
113
+ 2026-03-28
114
+
115
+ - MDX hydration: MDX documents now support hydration of embedded React components, allowing for interactive content within static pages.
116
+
117
+ - **Fixed Recent Activity tracking**: The Recent Activity widget now properly tracks when document content actually changed, rather than relying on file system modification times (mtime).
118
+ - Previously, Recent Activity used filesystem mtime, which doesn't work correctly after git clone (git doesn't preserve timestamps) or when all files are built simultaneously.
119
+ - Now, content change timestamps are stored in `.ursa.json` (in the source directory), which:
120
+ - Survives `--clean` builds (unlike the `.ursa/` cache folder)
121
+ - Can be committed to git to preserve wiki history across clones
122
+ - Falls back to file mtime for files that haven't been tracked yet (backward compatibility)
123
+ - Both full builds and single-file regeneration (serve/dev mode) now update content timestamps when content actually changes (detected by hash comparison).
124
+
125
+ # 0.80.1
126
+ 2026-02-16
127
+
128
+ - Fixed package.json issue
129
+
130
+ # 0.80.0
131
+ 2026-02-16
132
+
133
+ - Added remark extensions to ensure MDX has the same extended markdown features as regular markdown (e.g. footnotes, definition lists, etc.)
134
+
135
+ # 0.79.0
136
+ 2026-02-14
137
+
138
+ - Menu fixes:
139
+ - Zero-item submenus will no longer be hidden if they have subfolders with one+ item
140
+ - Bug fix for missing menu items
141
+ - Level 2+ menus now have overflow:scroll (vertical only)
142
+
143
+ # 0.78.0
144
+ 2026-02-13
145
+
146
+ - added release-it
147
+ - --clean now fully deletes the .ursa cache folder and clears the output directory before generation, ensuring a completely fresh build without any stale files. Previously, --clean only ignored the cache but left existing output files in place, which could cause issues with stale auto-generated indexes and other files blocking new generation. This change provides a more robust clean build experience.
148
+
149
+ # 0.77.0
150
+ 2026-02-13
151
+
152
+ QOL:
153
+ - When 'serve' encounters an occupied port 8080, prompt the user to find an available port instead of just exiting with an error. Will check open ports and find the closest port to 8080, then ask the user if they want to use it.
154
+
155
+ Meta cleanup:
156
+ - Templates should have their own folder, including default
157
+ - All static files for a template should be in the template's folder, and probably in the right subfolder (e.g. public/default.css should be in templates/default/public/default.css or something like that).
158
+ - Template filenames should be templates/{templateName}/index.html
159
+ - Ursa should throw a warning if it finds orphaned static files in meta that aren't referenced by a template
160
+
161
+ Static assets revamp:
162
+ - Revamped the building of static assets (stylesheets and scripts). The new logic is:
163
+ - All meta scripts and stylesheets should be bundled together into a single CSS file and a single JS file for the entire site. This applies to build mode; in dev mode, they are served individually for easier debugging and regeneration.
164
+ - Bundle-able document files (style.css, script.js, menu.md) will be bundled together on a per-folder basis. Each document will include the bundles from its own folder and all parent folders (where they exist).
165
+
166
+ Regeneration revamp:
167
+ - Existing logic:
168
+ - On first generation, save a cache of document output given some sort of hash of the source file and metadata (e.g. mtime, size, etc.)
169
+ - All static files (meta and document) should include a datetime or hash-based cache-buster in their query strings / filenames, so they can be invalidated as needed
170
+ - On subsequent generations, if the source file's hash is unchanged, skip regeneration and reuse the existing output file. (Note: this doesn't handle cases where the statis files changed and the document didn't; see below)
171
+ - Push a notification to the client when a file is regenerated, so the client can update the page if it's currently being viewed
172
+ - New logic is as above, plus: (some of this is partially complete, but these are the complete requirements)
173
+ - When any file being watched is changed, determine the list of affected files. For instance:
174
+ - A normal document will obviously invalidate that exact document.
175
+ - Special Ursa static files (menu.md, style.css, and script.js) are inherited by all documents in the current folder and all subfolders, so they will invalidate all documents in the current folder and all subfolders.
176
+ - Meta static files:
177
+ - A template file in meta will invalidate all documents that use that template.
178
+ - A stylesheet or script file in meta will invalidate all documents that inherit from that meta (which is probably everything).
179
+ - All other static files in the docroot (assuming they're linked at all by any document) should be invalidated thus:
180
+ - Calculate a new hash for the static file
181
+ - Find all documents that reference that static file
182
+ - Regenerate the html (even if the source md/mdx/txt file is unchanged) for those documents to update the cache-busting query string for the static file reference
183
+ - This should catch all the various edge cases that previously required restarting the server or doing a full regeneration.
184
+ - Regeneration priority order:
185
+ - When regeneration is triggered, check for connected WebSocket clients and get their current URL.
186
+ - If their current URL is affected by the change (document, static asset, template, anything), prioritize the necessary documents and assets to serve that URL before all others, and when they are regenerated, send the push notification to reload.
187
+ - After that, regenerate the rest of the affected documents in the background.
188
+ - In cases of rapid changing of files, do the following:
189
+ - Debounce all file system change events within a short time window (e.g. 500ms); wait for at least 500ms of no changes before starting regeneration. This helps in cases where a script or bot is making many changes to many files.
190
+ - When a change is detected, before any complex processing, send a ping to WebSocket-connected clients that an update is in progress, but it isn't known yet if it will affect their page.
191
+ - When it is determined that a change will affect the current page of a connected client, send another push to let the client know.
192
+ - Handle the above two notifications in the UI thus:
193
+ - When updates start, add a subtle loading indicator to the right of all left widgets, such as <Loader color="gray" />
194
+ - If it turns out the update doesn't need a refresh, remove the indicator.
195
+ - If it does need a refresh, change the indicator to a <Loader color="green" />.
196
+ - When the hot refresh actually happens, the indicator shouldn't be there anymore.
197
+ - Cache changes (under consideration):
198
+ - Before the cache was implemented, every file change triggered a complete regeneration of the entire site. This was slow, obviously. First, an in-memory cache was added to speed up the regeneration of unchanged files. But since the watcher back then missed a lot of regeneration cases (such as all meta changes), killing 'serve' and restarting it was quite common. Thus, the cache was persisted to disk, so that even in the case of a full regeneration (such as after a restart), unchanged files would still be skipped. This has worked fairly well, but for the invalidation edge cases described above (already fixed).
199
+ - However, considering that we now have a robust regeneration system that can handle all edge cases and push updates to the client, we may want to consider removing the cache entirely. The cache adds complexity and can sometimes get into a bad state, requiring manual deletion. With the new regeneration system, we could keep the cache in-memory, and rarely will the user need to kill 'serve' and restart just to get an update (ideally, never). In-memory cache is even faster than disk, so this might be a better experience overall.
200
+ - Regeneration cases still unhandled:
201
+ - User updates Ursa itself (e.g. npm update) while serve is active. I mean, this shouldn't be very common outside of Ursa devs, but's determine:
202
+ - Does the current system actually catch the meta changes?
203
+
204
+
205
+
206
+ Top Menu improvements:
207
+ - When a submenu overflows the available viewport height, it should become scrollable instead of overflowing off the screen. This can be achieved with CSS by setting a max-height and overflow-y: auto on the submenu container.
208
+
209
+ New Widgets:
210
+ - Suggested Content
211
+ - A new left-side widget that shows a list of suggested content based on the current page. Categories of suggested content:
212
+ - Content you frequently view (uses localStorage to track page views and show most viewed content)
213
+ - Future ideas:
214
+ - LLM-guided suggestions based on frequently viewed content, suggested related documents you haven't viewed yet, etc.
215
+
216
+ Bugs:
217
+ - [x] When using menu.md with auto-generation, the top menu's Home href is "//index.html" instead of "/index.html". On localhost, this ends up working fine, but on https://realdomain.com, this loads https://index.html which obviously doesn't work. The current logic seems to prefer absolute URLs, so in this case, the url for home should be "/index.html" (not double slash).
218
+ - [x] Site style.css is not present on auto-generated index pages
219
+ - Regeneration issues:
220
+ - Create a power, that power page now exists. But powers.json doesn't have it.
221
+
222
+ # 0.76.0
223
+ 2026-02-11
224
+
225
+ - **New Feature: Recent Activity widget.** A new topbar widget shows the 10 most recently modified documents in the docroot, sorted by modification date (most recent first). The widget appears on the left side of the top nav (to the right of the home icon) and is open by default.
226
+ - Recent activity data is collected during the generate phase by stat-ing each article file, then written to `public/recent-activity.json`.
227
+ - In serve/dev mode, the recent activity list is built during background cache initialization and updated live when article files are changed.
228
+ - The single-file regeneration path (`regenerateSingleFile`) also updates the recent activity JSON incrementally.
229
+ - **Widget system improvements:**
230
+ - All widgets now have a close (✕) button in the upper-right corner of their panel header. Clicking it closes the widget and deselects the corresponding icon in the top bar.
231
+ - Widget open/closed state is now persisted in localStorage. Widgets that were open will remain open after a page reload, and widgets that were closed will remain closed. Widgets with no saved state fall back to their default (Recent Activity defaults to open; others default to closed).
232
+ - The widget system now supports both left-side and right-side widget panels, which operate independently (one widget per side can be open at a time).
233
+
234
+ # 0.75.0
235
+ 2026-02-10
236
+
237
+ - Top Menu changes: the top menu is now the default first-level navigation. Top-left nav is either root, or 'hamburger' on smaller screens.
238
+ - Right column is now a standardized widget zone, with TOC, Search, and Profile widgets implemented.
239
+ - Default header: documents without an initial H1 will now have their title rendered as an H1 header at the top of the article. Index/home pages will default to the parent folder name if not overridden.
240
+ - Breadcrumbs: added breadcrumbs to the top of each article for easier navigation and context
241
+
242
+ # 0.74.0
243
+ 2026-02-08
244
+
245
+ - added a feature to skip preview generation and swapping on a per-image basis. You can use the data-no-preview tag in html, and the ?no-preview query parameter in markdown or wikitext images.
246
+ - when building automenus and autoindex pages, folders with no md/mdx/txt/html documents anywhere in their tree will not be shown.
247
+
248
+ # 0.73.0
249
+ 2026-02-07
250
+
251
+ - fixed build pipeline blocker
252
+
253
+ # 0.72.0
254
+ 2026-02-07
255
+
256
+ - MDX support: Ursa can now process .mdx files with embedded JSX components
257
+ - MDX files are parsed and rendered to HTML with React components
258
+ - Custom components can be imported and used within MDX content
259
+ - MDX documents are fully integrated with Ursa's build and serve processes, including hot reloading in dev mode
260
+ - This allows for rich interactive content while still benefiting from Ursa's static site generation features
261
+
262
+ # 0.71.0
263
+ 2026-02-05
264
+
265
+ - 'Dev mode': new mode similar to serve, but only generates documents on-demand to save time.
266
+ - When running `ursa dev`, the server starts immediately without a full build
267
+ - Documents are generated on-the-fly when requested, with caching for subsequent requests
268
+ - Ideal for development with large sites where full builds are slow
269
+ - Still supports hot reloading and file watching for dynamic updates
270
+ - Custom menus can now include auto-generated menus in addition to custom content
271
+ - Custom menus are displayed on the top bar instead of the side
272
+
273
+ # 0.70.0
274
+ 2026-02-04
275
+
276
+ - **Navigation Cache**: Dramatically improved navigation build time
277
+ - Navigation structure cached in `.ursa/nav-cache.json`
278
+ - Cache validated by file list hash + metadata file stats (index.md, config.json)
279
+ - Parallel stat operations for faster cache validation
280
+ - Result: Navigation build drops from ~9s to ~50ms on cached runs (99% improvement)
281
+
282
+ # 0.69.0
283
+ 2026-02-04
284
+
285
+ - **Image Processing Performance**: Dramatically improved image processing speed
286
+ - Persistent image cache: images are only re-processed when source file changes (mtime/size check)
287
+ - Parallel processing: 8 images processed concurrently instead of sequentially
288
+ - Smart preview skipping: images smaller than 800x800 skip preview generation (already small enough)
289
+ - Result: Image processing drops from ~23s to ~16ms on cached runs (99.9% improvement)
290
+
291
+ # 0.68.0
292
+ 2026-02-04
293
+
294
+ - **Build Performance Profiling**: Added comprehensive profiling to identify performance bottlenecks
295
+ - Each build phase is now timed with millisecond precision
296
+ - Visual bar chart report shows percentage of total build time per phase
297
+ - Phases tracked: Scan source files, Filter & classify, Build navigation, Load cache, Copy meta files, Process images, Process articles, Write search index, Write menu data, Process directories, Process static files, Auto-index generation, Finalization
298
+ - Report displayed at end of each build for performance analysis
299
+
300
+ # 0.67.0
301
+ 2026-02-04
302
+
303
+ - All images referenced in whitelisted documents should be processed and copied, even if the images themselves are not in the whitelist
304
+
305
+ # 0.66.0
306
+ 2026-02-04
307
+
308
+ - Links to a markdown file in source will now render as a link to the corresponding .html file even if the target file does not exist yet
309
+ - Relative URLs in raw HTML elements (img src, video src, etc.) embedded in markdown files are now resolved relative to the document's location
310
+ - Relative URLs in inline style `url()` values (e.g., `background-image: url('./img/foo.webp')`) are now resolved relative to the document's location
311
+
312
+ # 0.65.0
313
+ 2026-02-01
314
+
315
+ - Fixed issue where images wrapped in an anchor tag were incorrectly given a click handler to open in a new tab
316
+
317
+ # 0.64.0
318
+ 2026-01-31
319
+
320
+ - Handles scenario where a new image is added while serving (previously the image wouldn't show without a full restart)
321
+ - New images are now processed on-the-fly when detected in serve mode
322
+ - Image previews are generated and copied to output automatically
323
+ - HTML is updated to use preview images without needing a full rebuild
324
+
325
+ # 0.63.0
326
+ 2026-01-31
327
+
328
+ - Images inside an anchor tag will no longer have a click handler added to open the image in a new tab
329
+
330
+
331
+ # 0.62.2
332
+ 2026-01-29
333
+
334
+ - Fixed CI issue with pnpm using npm-specific syntax
335
+
336
+ # 0.62.1
337
+ 2026-01-29
338
+
339
+ - CI now uses pnpm to avoid redundant package managers
340
+
341
+ # 0.62.0
342
+ 2026-01-29
343
+
344
+ - **Enhanced Auto-Index**: Index documents can now configure auto-index generation via frontmatter
345
+ - `generate-auto-index: true` - Include an auto-generated index listing in the page
346
+ - `auto-index-depth: N` - Control recursion depth (1 = current folder, 2 = current + subfolders, etc.)
347
+ - `auto-index-position: top|bottom` - Insert the auto-index before or after the document content
348
+
349
+ - **Faster Serve Mode**: The `serve` command now uses deferred image processing for significantly faster startup
350
+ - HTML files are generated immediately with original image paths
351
+ - Image preview generation runs in the background after HTML is ready
352
+ - Site is browsable within seconds instead of waiting for full image processing
353
+ - Images will display as originals until preview generation completes (then show optimized WebP previews)
354
+ - Added hot reloading for regeneration
355
+
356
+ - **Bug Fixes**:
357
+ - Fixed issue where style.css changes were not reflected until server restart in `serve` mode
358
+ - Fixed issue where root-level auto-index had incorrect HREFs
359
+ - Fixed issue where re-generating an index document with `generate-auto-index:true` did not include the auto-index until server restart
360
+ - Fixed issue where auto-indexer was rendering 'img' folders
361
+
362
+ # 0.61.1
363
+ 2026-01-14
364
+
365
+ - Fix: package-lock.json version mismatch
366
+
367
+ # 0.61.0
368
+ 2026-01-14
369
+
370
+ - Image Handling
371
+ - [x] When an image tag is encountered, and the image is found in the static assets:
372
+ - [x] Process the image to a preview size (max width/height == article width (50rem) or px equivalent), and convert to webp with reasonable compression. Copy the original image as well as the preview.
373
+ - [x] Generate the HTML img tag as is currently done, but:
374
+ - [x] Use the preview image as the src
375
+ - [x] Use the original image as the data-fullsrc attribute
376
+ - [x] On click, open the original image in a new tab
377
+
378
+ # 0.60.0
379
+ 2026-01-03
380
+
381
+ - added `menu-label` frontmatter field to override default menu labels
382
+ - added `menu-sort-as` frontmatter field for custom sort ordering
383
+ - metadata-only index.md files now trigger auto-index generation
384
+ - index files sorted to top of menu panes with distinct styling
385
+ - fixed menu column vertical scrolling
386
+ - excluded Ursa-internal fields from frontmatter table display
387
+
388
+ # 0.59.0
389
+ 2026-01-01
390
+
391
+ - added frontmatter rendering
392
+
393
+ # 0.58.0
394
+ 2025-12-26
395
+
396
+ - new menu UI with 2-pane horizontal layout
397
+
398
+ # 0.57.0
399
+ 2025-12-26
400
+
401
+ - added full-text indexing and search using lunr.js
402
+ - all links in generated html will be full links with extensions (e.g. /folder/page.html)
403
+
404
+ # 0.56.0
405
+ 2025-12-23
406
+
407
+ - restored metadata to directory index JSON files
408
+
409
+ # 0.55.0
410
+ 2025-12-21
411
+
412
+ - custom menus (menu.md|txt) override the automenu when present
413
+
414
+ # 0.54.0
415
+ 2025-12-21
416
+
417
+ - added cache-busting timestamps to static files
418
+ - cleaned up generate.js by moving helper functions to separate files
419
+
420
+
421
+ # 0.53.0
422
+ 2025-12-21
423
+
424
+ ### Menu Size Optimization
425
+ - **External Menu JSON**: Menu data is now stored in `/public/menu-data.json` instead of being embedded in every HTML file. This dramatically reduces HTML file sizes for sites with large folder structures (e.g., from 2-3MB per file down to ~50KB).
426
+ - **Async Menu Loading**: Menu data is fetched asynchronously after page render, showing a "Loading menu..." indicator until ready.
427
+ - **Debug Fields Removed**: Menu JSON no longer includes debug/inactive fields, reducing JSON size further.
428
+ - **Gzip Compression**: Development server now uses gzip compression for all responses, significantly reducing transfer size for JSON and HTML files.
429
+
430
+ # 0.52.0
431
+ 2025-12-21
432
+
433
+ - Fixed search results not displaying correctly when no matches are found
434
+
435
+ # 0.51.0
436
+ 2025-12-21
437
+
438
+ - Existing .html files are no longer overwritten by generated documents.
439
+
440
+ # 0.50.0
441
+ 2025-12-21
442
+
443
+ ### Performance Optimizations
444
+ - **CSS Path Caching**: Implemented caching for `findStyleCss()` lookups during generation. Reduces redundant filesystem walks for documents in the same directory tree.
445
+ - **Template Replacement Optimization**: Changed from 8 sequential `string.replace()` calls to a single regex pass, reducing intermediate string allocations.
446
+ - **Wikitext Regex Pre-compilation**: Pre-compiled ~40 regex patterns at module load time instead of compiling on every `wikiToHtml()` call.
447
+
448
+ ### New Features
449
+ - **Static File Watch**: `ursa serve` now watches for new/changed static files (images, fonts, PDFs, etc.) and automatically copies them to output without requiring a full rebuild.
450
+
451
+ ### Bug Fixes
452
+ - **Menu Folder Expansion**: Fixed issue where navigating to `/folder` wouldn't auto-expand the menu, but `/folder/index.html` would. Both now behave consistently by normalizing trailing slashes in URL comparison.
453
+
454
+
455
+ # 0.49.0
456
+ 2025-12-20
457
+
458
+ - Fixed more instances of false inactive links, this time in wikitext files (.txt)
459
+ - **Auto-Index Style Fix**: Auto-generated index pages now correctly inherit `style.css` from parent folders, just like normal documents
460
+ - **Clean Build Fix**: The `--clean` flag now properly clears the output directory before generation. Previously it only ignored the hash cache, which could leave stale files (like old auto-generated indexes) that would block new generation.
461
+
462
+
463
+ # 0.48.0
464
+ 2025-12-20
465
+
466
+ - **External CSS**: CSS files are now externally linked via `<link>` tags instead of being embedded in each HTML page. This significantly reduces HTML file sizes and improves browser caching.
467
+ - **Fast CSS Updates**: CSS file changes in watch mode now just copy the file to output (~1ms) instead of triggering a full rebuild
468
+ - **Fast Single-File Regeneration**: Article changes in watch mode use a new fast-path that regenerates only the changed file (~50-100ms) instead of scanning all source files
469
+ - **Clickable Folder Links**: All folders in the navigation menu are now clickable links (auto-index ensures every folder has an index.html)
470
+ - **Menu Collapse Fix**: Fixed issue where clicking the caret on a folder containing the current page wouldn't collapse it
471
+ - **URL Encoding Fix**: Fixed menu not highlighting current page when URLs contain spaces or special characters
472
+ - **Link Validation Fix**: Links to folders are no longer incorrectly marked as inactive (folders now included in valid paths since auto-index generates index.html for all)
473
+ - **WikiText Link Fix**: Fixed wikitext links (in .txt files) being incorrectly marked as inactive. Link validation is now handled centrally by the link validator after HTML generation.
474
+ - **Folder/Index Link Fix**: Links to folders containing a `(foldername).md` file (instead of `index.md`) are now correctly recognized as valid
475
+
476
+ # 0.47.0
477
+ 2025-12-20
478
+
479
+ - Improved handling of trailing slashes in URLs to ensure consistency across all links and resources
480
+
481
+ # 0.46.0
482
+ 2025-12-20
483
+
484
+ - Normalized handling of trailing slashes in URLs
485
+
486
+ # 0.45.0
487
+ 2025-12-20
488
+
489
+ - Added --exclude flag to ignore specified files or directories during generation
490
+ - Improved performance of the serve command with optimized file watching
491
+ - Automatically generating index.html for directories without an index file
492
+
493
+ # 0.44.0
494
+ 2025-12-16
495
+
496
+ - Added 'sections' metadata property with hierarchical section structure
497
+
498
+ # 0.43.0
499
+ 2025-12-14
500
+
501
+ - Added buildId and .ursa.json
502
+ - Added full datetime to footer
503
+ - Added commit hash to footer as comment
504
+
505
+ # 0.42.0
506
+ 2025-12-14
507
+
508
+ - Automenu will now remove dashes from file names
509
+
510
+ # 0.41.0
511
+ 2025-12-13
512
+
513
+ - Fixed footer bug
514
+
515
+ # 0.40.0
516
+ 2025-12-13
517
+
518
+ - Added footer
519
+
520
+ # 0.39.0
521
+ 2025-12-13
522
+
523
+ - Updated to node 24.5 to satisfy npm Trusted Publishing
524
+ - Refactored Github Actions
525
+ - Added CONTRIBUTING.md
526
+
527
+ # 0.38.0
528
+ 2025-12-13
529
+
530
+ - Updated Github Actions workflow to use OIDC for authentication
531
+
532
+ # 0.37.0
533
+ 2025-12-13
534
+
535
+ - Added Github Actions workflow for CI/CD (npm publish)
536
+
537
+ # 0.36.0
538
+ 2025-12-13
539
+
540
+ - Links to a valid .md file in source will now render as a link to the corresponding .html file (and show as an active link)
541
+
542
+ # 0.35.0
543
+ 2025-12-11
544
+
545
+ - Fixed issue where directory indices were empty
546
+
547
+ # 0.34.0
548
+ 2025-12-11
549
+
550
+ - Added config.json with folder-specific settings for label, icon, and visibility
551
+ - Root-level config.json can specify open menu items
552
+
553
+ # 0.33
554
+ 2025-12-10
555
+
556
+ - Fixed the broke-ass menu
557
+
558
+ # 0.32
559
+ 2025-12-10
560
+
561
+ - Using .ursa folder in source directory for content hash cache
562
+ - Added --clean flag to ignore cache and regenerate all files
563
+ - Set up npm config for public package publishing
564
+
565
+ # 0.31
566
+ 2025-12-09
567
+
568
+ - Added URL property to JSON directory indices
569
+ - Ensured directory indices are recursive
570
+
571
+ # 0.30
572
+ 2025-12-07
573
+
574
+ - Fixed broken link detection to correctly identify broken internal links
575
+
576
+ # 0.29.0
577
+ 2025-12-07
578
+
579
+ - New nav-main style, two-levels only (but supports any depth), looks way better
580
+
581
+ # 0.28.0
582
+ 2025-12-07
583
+
584
+ - Added broken link detection and styles
585
+ - Fixed hole in "serve" logic that didn't regenerate style.css
586
+
587
+ # 0.27.0
588
+ 2025-12-07
589
+
590
+ - Capitalizing nav-main labels
591
+
592
+ # 0.26.0
593
+ 2025-12-06
594
+ - Fixed global nav styles in desktop
595
+ - Updated main nav style to match TOC
596
+
597
+ # 0.25.0
598
+
599
+ 2025-12-06
600
+
601
+ - Enhanced mobile navigation with hamburger toggle that changes to X when menu is open
602
+ - Improved button accessibility with dynamic aria-label updates
603
+
604
+ # 0.24.0
605
+
606
+ 2025-12-06
607
+
608
+ - Added support for index files in folder links
609
+ - Folders with index.md/txt/yml now link to /folder/index.html
610
+ - Folders without index files render as non-clickable text
611
+
612
+ # 0.23.0
613
+
614
+ 2025-12-04
615
+
616
+ - Implemented incremental build support with content hashing
617
+ - Source file changes now only regenerate modified files
618
+ - Meta file changes still trigger full rebuild
619
+ - Added .content-hashes.json cache for tracking file changes
620
+
621
+ # 0.22.0
622
+
623
+ 2025-12-04
624
+
625
+ - New Notion-style nav-main sidebar design
626
+ - Added folder/document icons with custom icon support
627
+ - Collapsible menu items with expand arrows
628
+ - Responsive flexbox layout for nav-global
629
+
630
+ # 0.21.0
631
+
632
+ 2025-12-01
633
+
634
+ - Enhanced error handling for template retrieval
635
+ - Better error messages when templates are not found
636
+
637
+ # 0.20.0
638
+
639
+ 2025-12-01
640
+
641
+ - Added fault tolerance to generate command
642
+ - Individual file errors no longer stop entire build
643
+ - Errors collected and written to _errors.log
644
+
645
+ # 0.19.0
646
+
647
+ 2025-11-21
648
+
649
+ - Fixed YAML parsing issues with horizontal rules being mistaken for front matter
650
+ - Improved regex to require closing --- on its own line
651
+
652
+ # 0.18.0
653
+
654
+ 2025-11-21
655
+
656
+ - Fixed errors with wikitext rendering
657
+ - Better handling of undefined args.db
658
+
659
+ # 0.17.0
660
+
661
+ 2025-10-23
662
+
663
+ - Added Table of Contents (TOC) generation
664
+ - Smooth scrolling to headings with offset adjustment
665
+ - Active heading tracking in TOC
666
+
667
+ # 0.16.0
668
+
669
+ 2025-10-22
670
+
671
+ - AI-implemented search feature with typeahead
672
+ - Search index built from all articles during generation
673
+
674
+ # 0.15.0
675
+
676
+ 2025-10-22
677
+
678
+ - Improved mobile responsiveness
679
+ - Better media query breakpoint (800px)
680
+ - Enhanced h1 styling and article width for mobile
681
+
682
+ # 0.14.0
683
+
684
+ 2025-10-22
685
+
686
+ - Fixed sticky header generation
687
+ - Enhanced sticky header functionality
688
+ - Added responsive navigation styles
689
+
690
+ # 0.13.0
691
+
692
+ 2025-10-07
693
+
694
+ - Added whitelist feature for selective file generation
695
+ - Added sectionify script for content organization
696
+ - Fixed bugs in node-watch for file monitoring
697
+ - Working sticky headers implementation
698
+
699
+ # 0.12.0
700
+
701
+ 2025-10-06
702
+
703
+ - Added debug CLI mode
704
+ - Fixed embedded style issues
705
+ - Added site navigation
706
+ - Total rewrite of base CSS (article and topnav)
707
+ - Added custom CSS support (disabled by default)
708
+
709
+ # 0.11.0
710
+
711
+ 2025-07-28
712
+
713
+ - added CLI commands (e.g. "ursa src" and "ursa serve src")
714
+
715
+ # 0.10.0
716
+
717
+ 2024-03-13
718
+
719
+ - Will no longer write an autoindex when index document already exists
720
+
721
+ # 0.9.0
722
+
723
+ 2024-02-10
724
+
725
+ - Removed spammy debug data from json
726
+
727
+ # 0.8.0
728
+
729
+ 2023-12-31
730
+
731
+ - Fixed recursive-readdir to actually return directories, not just files
732
+
733
+ # 0.7.0
734
+
735
+ 2023-08-01
736
+
737
+ - removed all non-public modules
738
+
739
+ # 0.6.0
740
+
741
+ 2023-08-01
742
+
743
+ - removed some dependencies that required private auth for npm install
744
+
745
+ # 0.5.0
746
+
747
+ 2023-05-08
748
+
749
+ - added INCLUDE_FILTER env var
750
+
751
+ # 0.4.2
752
+
753
+ 2023-03-01
754
+
755
+ - bug fixes
756
+
757
+ # 0.4.0
758
+
759
+ 2023-03-31
760
+
761
+ - Now a library
762
+
763
+ # 0.3.0
764
+
765
+ 2022-10-17
766
+
767
+ - Using express instead of http/node-static for serve
768
+ - Serve now waits for generation to finish
769
+ - Formatted files using prettier
770
+
771
+ # 0.2.0
772
+
773
+ 2022-03-30
774
+
775
+ - Added serve command
776
+ - Workaround for node-static broken npm package
777
+ - Added source static files and menu
778
+ - Lots of default styling (not that meta should be in there at all)
779
+ - Added TODO
780
+
781
+ # 0.1.0
782
+
783
+ 2022-03-30
784
+
785
+ - Initial POC