pict-section-inlinedocumentation 0.0.1

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 (51) hide show
  1. package/README.md +107 -0
  2. package/docs/.nojekyll +0 -0
  3. package/docs/README.md +83 -0
  4. package/docs/_cover.md +15 -0
  5. package/docs/_sidebar.md +24 -0
  6. package/docs/_topbar.md +8 -0
  7. package/docs/_version.json +7 -0
  8. package/docs/api-reference.md +185 -0
  9. package/docs/architecture.md +103 -0
  10. package/docs/css/docuserve.css +327 -0
  11. package/docs/embedding-level1-sidebar.md +92 -0
  12. package/docs/embedding-level2-routes.md +86 -0
  13. package/docs/embedding-level3-tooltips.md +97 -0
  14. package/docs/embedding-level4-autogen.md +126 -0
  15. package/docs/index.html +39 -0
  16. package/docs/overview.md +42 -0
  17. package/docs/quickstart.md +95 -0
  18. package/docs/reference.md +73 -0
  19. package/docs/retold-catalog.json +181 -0
  20. package/docs/retold-keyword-index.json +4374 -0
  21. package/example_applications/basic/docs/README.md +40 -0
  22. package/example_applications/basic/docs/_sidebar.md +4 -0
  23. package/example_applications/basic/docs/_topics.json +10 -0
  24. package/example_applications/basic/docs/advanced-topics.md +47 -0
  25. package/example_applications/basic/docs/getting-started.md +70 -0
  26. package/example_applications/basic/index.html +100 -0
  27. package/example_applications/bookshop/.quackage.json +10 -0
  28. package/example_applications/bookshop/Pict-Application-Bookshop-Configuration.json +15 -0
  29. package/example_applications/bookshop/Pict-Application-Bookshop.js +218 -0
  30. package/example_applications/bookshop/data/BookshopData.json +65 -0
  31. package/example_applications/bookshop/data/pict_documentation_topics.json +46 -0
  32. package/example_applications/bookshop/docs/_sidebar.md +6 -0
  33. package/example_applications/bookshop/docs/book-detail.md +21 -0
  34. package/example_applications/bookshop/docs/book-list.md +21 -0
  35. package/example_applications/bookshop/docs/search-filter.md +18 -0
  36. package/example_applications/bookshop/docs/store.md +29 -0
  37. package/example_applications/bookshop/docs/welcome.md +23 -0
  38. package/example_applications/bookshop/html/index.html +236 -0
  39. package/example_applications/bookshop/package.json +34 -0
  40. package/example_applications/bookshop/views/PictView-Bookshop-BookList.js +324 -0
  41. package/example_applications/bookshop/views/PictView-Bookshop-HelpToggle.js +44 -0
  42. package/example_applications/bookshop/views/PictView-Bookshop-Store.js +271 -0
  43. package/package.json +55 -0
  44. package/source/Pict-Section-InlineDocumentation.js +10 -0
  45. package/source/providers/Pict-Provider-InlineDocumentation.js +1995 -0
  46. package/source/views/Pict-View-InlineDocumentation-Content.js +542 -0
  47. package/source/views/Pict-View-InlineDocumentation-Layout.js +206 -0
  48. package/source/views/Pict-View-InlineDocumentation-Nav.js +475 -0
  49. package/source/views/Pict-View-InlineDocumentation-TopicManager.js +1623 -0
  50. package/test/Browser_Integration_tests.js +1449 -0
  51. package/test/Pict-Section-InlineDocumentation_test.js +1285 -0
package/README.md ADDED
@@ -0,0 +1,107 @@
1
+ # pict-section-inlinedocumentation
2
+
3
+ > Embed context-aware documentation and tooltip help directly inside any Pict application.
4
+
5
+ A Pict section that turns a folder of Markdown files into in-app help. Ships four progressively deeper embedding modes: a drop-in sidebar with a table of contents, route-mapped reading panes, hand-authored tooltips on specific controls, and auto-generated tooltips for every Manyfest-managed control in your app -- editable live when a content owner is signed in.
6
+
7
+ Part of the [Retold](https://github.com/stevenvelozo/retold) suite.
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install pict-section-inlinedocumentation
13
+ ```
14
+
15
+ ## Quick Usage
16
+
17
+ ```js
18
+ const libPict = require('pict');
19
+ const libInlineDocs = require('pict-section-inlinedocumentation');
20
+
21
+ const _Pict = new libPict({ Product: 'My App', Version: '1.0.0' });
22
+
23
+ _Pict.addSection('InlineDocumentation', libInlineDocs,
24
+ {
25
+ DocumentationRoot: '/docs/',
26
+ CatalogURL: '/docs/retold-catalog.json',
27
+ DefaultTopic: 'overview',
28
+ SidebarContainer: '#AppHelpSidebar'
29
+ });
30
+
31
+ _Pict.onAfterInitializeAsync = async () =>
32
+ {
33
+ await _Pict.views.InlineDocumentation.renderAsync();
34
+ };
35
+ ```
36
+
37
+ Add a container to your HTML and you're done:
38
+
39
+ ```html
40
+ <aside id="AppHelpSidebar"></aside>
41
+ ```
42
+
43
+ ## Four Levels of Embeddedness
44
+
45
+ ```mermaid
46
+ flowchart LR
47
+ L1[1. Sidebar + ToC] --> L2[2. Route-Mapped]
48
+ L2 --> L3[3. Hand-Authored Tooltips]
49
+ L3 --> L4[4. Auto-Generated Tooltips]
50
+ ```
51
+
52
+ | Level | What you get | Effort |
53
+ |---|---|---|
54
+ | 1 | Sidebar with a ToC of every topic | A few lines of config |
55
+ | 2 | Help pane tracks the current route | Add a route map |
56
+ | 3 | Tooltips on specific controls | `data-help` per control |
57
+ | 4 | Tooltips on **every** Manyfest control, editable in-app | One call per form |
58
+
59
+ Each level is a strict superset of the one below it.
60
+
61
+ ## Highlights
62
+
63
+ - Built on `pict-view`, integrates with `pict-router`
64
+ - Consumes `retold-catalog.json` + `retold-keyword-index.json` from `pict-docuserve`
65
+ - Safe Markdown renderer with Mermaid, code highlighting, and KaTeX
66
+ - MutationObserver keeps tooltips bound as the DOM changes
67
+ - Edit mode: content editors can rewrite topics from the running app and POST them back
68
+ - Emits lifecycle events for analytics and audit
69
+
70
+ ## Scripts
71
+
72
+ | Script | What it does |
73
+ |---|---|
74
+ | `npm test` | Run Mocha TDD test suite |
75
+ | `npm run coverage` | Code coverage via nyc/Istanbul |
76
+ | `npx quack build` | Build the browser bundle |
77
+
78
+ ## Documentation
79
+
80
+ Full documentation lives in [`docs/`](./docs/) and is published via [pict-docuserve](https://github.com/stevenvelozo/pict-docuserve):
81
+
82
+ - [Overview](./docs/overview.md)
83
+ - [Quickstart](./docs/quickstart.md)
84
+ - [Architecture](./docs/architecture.md)
85
+ - [Implementation Reference](./docs/reference.md)
86
+ - [API Reference](./docs/api-reference.md)
87
+ - Embedding: [Level 1](./docs/embedding-level1-sidebar.md) · [Level 2](./docs/embedding-level2-routes.md) · [Level 3](./docs/embedding-level3-tooltips.md) · [Level 4](./docs/embedding-level4-autogen.md)
88
+
89
+ Regenerate the catalog and keyword index after editing any Markdown file:
90
+
91
+ ```bash
92
+ npx quack prepare-docs
93
+ ```
94
+
95
+ ## Relationship to Other Retold Modules
96
+
97
+ | Module | Role |
98
+ |---|---|
99
+ | [pict](https://github.com/stevenvelozo/pict) | Application framework |
100
+ | [pict-view](https://github.com/stevenvelozo/pict-view) | Base view class |
101
+ | [pict-router](https://github.com/stevenvelozo/pict-router) | Route change source for Level 2 |
102
+ | [pict-docuserve](https://github.com/stevenvelozo/pict-docuserve) | Catalog + keyword index producer |
103
+ | [manyfest](https://github.com/stevenvelozo/manyfest) | Descriptors walked for Level 4 |
104
+
105
+ ## License
106
+
107
+ [MIT](./LICENSE) -- same as the rest of the Retold suite.
package/docs/.nojekyll ADDED
File without changes
package/docs/README.md ADDED
@@ -0,0 +1,83 @@
1
+ # pict-section-inlinedocumentation
2
+
3
+ > Embed context-aware documentation and tooltip help directly inside any Pict application.
4
+
5
+ `pict-section-inlinedocumentation` is a Pict section that turns a folder of Markdown topics into in-app help. It spans the full spectrum from "a sidebar with a table of contents" to "every editable control on every screen has a live, editable tooltip" -- and you pick the level that matches your product.
6
+
7
+ Part of the [Retold](https://github.com/stevenvelozo/retold) suite. Uses [`pict-view`](/pict/pict-view/) as its base, optionally consumes catalogs from [`pict-docuserve`](/pict/pict-docuserve/), and at the deepest level pairs with [`manyfest`](/utility/manyfest/) to auto-generate tooltips for every descriptor in your model.
8
+
9
+ ## Four Levels of Embeddedness
10
+
11
+ ```mermaid
12
+ flowchart LR
13
+ L1[1. Sidebar + ToC] --> L2[2. Route-Mapped Content]
14
+ L2 --> L3[3. Hand-Authored Tooltips]
15
+ L3 --> L4[4. Auto-Generated Tooltips]
16
+
17
+ style L1 fill:#e3f2fd,stroke:#42a5f5,color:#333
18
+ style L2 fill:#e8f5e9,stroke:#66bb6a,color:#333
19
+ style L3 fill:#fff3e0,stroke:#ffa726,color:#333
20
+ style L4 fill:#fce4ec,stroke:#ef5350,color:#333
21
+ ```
22
+
23
+ Each level is a strict superset of the one before it.
24
+
25
+ ## Documentation
26
+
27
+ Published with [`pict-docuserve`](/pict/pict-docuserve/). Open `docs/index.html` locally, or browse the source Markdown:
28
+
29
+ - **[Overview](overview.md)** -- what it does and why
30
+ - **[Quickstart](quickstart.md)** -- sidebar running in five minutes
31
+ - **[Architecture](architecture.md)** -- services, views, lifecycle, with a Mermaid diagram
32
+ - **[Implementation Reference](reference.md)** -- source tree tour
33
+ - **[API Reference](api-reference.md)** -- every exposed function with a runnable snippet
34
+
35
+ ### Embedding Guides
36
+
37
+ - **[Level 1 -- Sidebar + ToC](embedding-level1-sidebar.md)** -- least embedded
38
+ - **[Level 2 -- Route-Mapped Content](embedding-level2-routes.md)** -- more embedded
39
+ - **[Level 3 -- Hand-Authored Tooltips](embedding-level3-tooltips.md)** -- somewhat embedded
40
+ - **[Level 4 -- Auto-Generated Tooltips](embedding-level4-autogen.md)** -- most embedded
41
+
42
+ ## Installation
43
+
44
+ ```bash
45
+ npm install pict-section-inlinedocumentation
46
+ ```
47
+
48
+ ## Tiny Example
49
+
50
+ ```js
51
+ const libPict = require('pict');
52
+ const libInlineDocs = require('pict-section-inlinedocumentation');
53
+
54
+ const _Pict = new libPict({ Product: 'My App', Version: '1.0.0' });
55
+
56
+ _Pict.addSection('InlineDocumentation', libInlineDocs,
57
+ {
58
+ DocumentationRoot: '/docs/',
59
+ CatalogURL: '/docs/retold-catalog.json',
60
+ DefaultTopic: 'overview',
61
+ SidebarContainer: '#AppHelpSidebar'
62
+ });
63
+
64
+ _Pict.onAfterInitializeAsync = async () =>
65
+ {
66
+ await _Pict.views.InlineDocumentation.renderAsync();
67
+ };
68
+ ```
69
+
70
+ ## Relationship to Other Modules
71
+
72
+ | Module | Role |
73
+ |---|---|
74
+ | [pict](/pict/pict/) | Application framework |
75
+ | [pict-view](/pict/pict-view/) | Base view class |
76
+ | [pict-router](/pict/pict-router/) | Source of route change events for Level 2 |
77
+ | [pict-docuserve](/pict/pict-docuserve/) | Produces the catalog and keyword index consumed by this section |
78
+ | [pict-template-markdown](/pict/pict-template-markdown/) | Markdown -> HTML renderer |
79
+ | [manyfest](/utility/manyfest/) | Descriptors walked by Level 4 auto-generation |
80
+
81
+ ## License
82
+
83
+ MIT -- same as the rest of the Retold suite.
package/docs/_cover.md ADDED
@@ -0,0 +1,15 @@
1
+ # pict-section-inlinedocumentation
2
+
3
+ > Embed context-aware documentation and tooltip help directly inside any Pict application.
4
+
5
+ A Pict section that turns Markdown documentation into in-app help -- from a simple sidebar ToC all the way to auto-generated tooltips for every editable control in your application. Four levels of embeddedness, one tiny API.
6
+
7
+ - **Level 1** -- Sidebar + ToC drop-in
8
+ - **Level 2** -- Route-pattern-mapped content
9
+ - **Level 3** -- Hand-authored tooltip topics
10
+ - **Level 4** -- Auto-generated tooltips for every manifest-managed control
11
+
12
+ [Get Started](#/page/quickstart.md)
13
+ [Architecture](#/page/architecture.md)
14
+ [API Reference](#/page/api-reference.md)
15
+ [GitHub](https://github.com/stevenvelozo/retold)
@@ -0,0 +1,24 @@
1
+ - Introduction
2
+
3
+ - [Overview](#/page/overview.md)
4
+ - [Quickstart](#/page/quickstart.md)
5
+
6
+ - Design
7
+
8
+ - [Architecture](#/page/architecture.md)
9
+ - [Implementation Reference](#/page/reference.md)
10
+ - [API Reference](#/page/api-reference.md)
11
+
12
+ - Embedding Levels
13
+
14
+ - [1. Sidebar + ToC](#/page/embedding-level1-sidebar.md)
15
+ - [2. Route-Mapped Content](#/page/embedding-level2-routes.md)
16
+ - [3. Hand-Authored Tooltips](#/page/embedding-level3-tooltips.md)
17
+ - [4. Auto-Generated Tooltips](#/page/embedding-level4-autogen.md)
18
+
19
+ - Ecosystem
20
+
21
+ - [pict](/pict/pict/)
22
+ - [pict-view](/pict/pict-view/)
23
+ - [pict-docuserve](/pict/pict-docuserve/)
24
+ - [manyfest](/utility/manyfest/)
@@ -0,0 +1,8 @@
1
+ # pict-section-inlinedocumentation
2
+
3
+ - [Overview](#/page/overview.md)
4
+ - [Quickstart](#/page/quickstart.md)
5
+ - [Architecture](#/page/architecture.md)
6
+ - [API](#/page/api-reference.md)
7
+ - [Embedding](#/page/embedding-level1-sidebar.md)
8
+ - [GitHub](https://github.com/stevenvelozo/retold)
@@ -0,0 +1,7 @@
1
+ {
2
+ "Name": "pict-section-inlinedocumentation",
3
+ "Version": "0.0.1",
4
+ "Description": "Pict embeddable inline documentation browser with topic support",
5
+ "GeneratedAt": "2026-04-10T17:25:27.594Z",
6
+ "GitCommit": "530ff7d"
7
+ }
@@ -0,0 +1,185 @@
1
+ # API Reference
2
+
3
+ Every function a developer is expected to call, with a working snippet for each.
4
+
5
+ The section is reached via `_Pict.views.InlineDocumentation` after it has been registered with `_Pict.addSection('InlineDocumentation', libInlineDocs, config)`.
6
+
7
+ ---
8
+
9
+ ## `renderAsync()`
10
+
11
+ Renders the sidebar and reading pane into their configured containers. Call once after the Pict application has initialized.
12
+
13
+ ```js
14
+ await _Pict.views.InlineDocumentation.renderAsync();
15
+ ```
16
+
17
+ ---
18
+
19
+ ## `loadTopicAsync(pTopicKey)`
20
+
21
+ Loads a single topic by key and renders it into the reading pane. Returns the parsed topic object.
22
+
23
+ ```js
24
+ const tmpTopic = await _Pict.views.InlineDocumentation.loadTopicAsync('records/editing');
25
+ console.log(tmpTopic.Title, tmpTopic.Category);
26
+ ```
27
+
28
+ ---
29
+
30
+ ## `getTopicAsync(pTopicKey)`
31
+
32
+ Returns the parsed topic without touching the DOM. Useful when you want the HTML for your own rendering.
33
+
34
+ ```js
35
+ const tmpTopic = await _Pict.views.InlineDocumentation.getTopicAsync('customers/email-field');
36
+ document.getElementById('MyCustomPane').innerHTML = tmpTopic.HTML;
37
+ ```
38
+
39
+ ---
40
+
41
+ ## `setDefaultTopic(pTopicKey)`
42
+
43
+ Changes the topic rendered when nothing else is selected.
44
+
45
+ ```js
46
+ _Pict.views.InlineDocumentation.setDefaultTopic('getting-started');
47
+ ```
48
+
49
+ ---
50
+
51
+ ## `setRouteMap(pRouteMap)`
52
+
53
+ Replaces the route map at runtime. Entries are matched top-down; the first match wins.
54
+
55
+ ```js
56
+ _Pict.views.InlineDocumentation.setRouteMap(
57
+ [
58
+ { Pattern: '/records/:entity', Topic: 'records/browsing' },
59
+ { Pattern: '/records/:entity/:id/edit', Topic: 'records/editing' },
60
+ { Pattern: '/settings/*', Topic: 'settings' }
61
+ ]);
62
+ ```
63
+
64
+ ---
65
+
66
+ ## `attachRouter(pRouter)`
67
+
68
+ Subscribes to a `pict-router` instance so that route changes drive the reading pane.
69
+
70
+ ```js
71
+ _Pict.views.InlineDocumentation.attachRouter(_Pict.providers.Router);
72
+ ```
73
+
74
+ ---
75
+
76
+ ## `bindTooltipsAsync(pScopeSelector)`
77
+
78
+ Finds every element with a `data-help` attribute under the given selector and wires a tooltip to it. Safe to call multiple times; already-bound elements are skipped.
79
+
80
+ ```js
81
+ await _Pict.views.InlineDocumentation.bindTooltipsAsync('#CustomerForm');
82
+ ```
83
+
84
+ ---
85
+
86
+ ## `unbindTooltips(pScopeSelector)`
87
+
88
+ Removes tooltip wiring for a scope. Use before destroying a view to avoid leaked listeners.
89
+
90
+ ```js
91
+ _Pict.views.InlineDocumentation.unbindTooltips('#CustomerForm');
92
+ ```
93
+
94
+ ---
95
+
96
+ ## `showTooltip(pElement, pTopicKey)`
97
+
98
+ Imperatively shows a tooltip -- handy for validation errors that carry a topic reference.
99
+
100
+ ```js
101
+ const tmpInput = document.getElementById('CustomerEmail');
102
+ _Pict.views.InlineDocumentation.showTooltip(tmpInput, 'customers/email-invalid');
103
+ ```
104
+
105
+ ---
106
+
107
+ ## `hideTooltip()`
108
+
109
+ Hides any currently visible tooltip.
110
+
111
+ ```js
112
+ _Pict.views.InlineDocumentation.hideTooltip();
113
+ ```
114
+
115
+ ---
116
+
117
+ ## `autoGenerateTooltipsAsync(pOptions)`
118
+
119
+ Walks a Manyfest descriptor, creates topic keys for every hash, and binds tooltips to the matching DOM controls. In `EditMode`, stub topics are created for missing keys and can be edited from the app.
120
+
121
+ ```js
122
+ await _Pict.views.InlineDocumentation.autoGenerateTooltipsAsync(
123
+ {
124
+ Manyfest: _Pict.providers.CustomerManyfest,
125
+ Scope: '#CustomerForm',
126
+ TopicPrefix: 'customers/',
127
+ EditMode: _Pict.providers.Auth.userHasRole('docs-editor')
128
+ });
129
+ ```
130
+
131
+ ---
132
+
133
+ ## `registerTopicStub(pTopicKey, pStub)`
134
+
135
+ Adds a stub topic in memory. Useful for testing or for supplying fallback content when the corpus is incomplete.
136
+
137
+ ```js
138
+ _Pict.views.InlineDocumentation.registerTopicStub('customers/email-field',
139
+ {
140
+ Title: 'Customer Email',
141
+ Markdown: 'The primary email address used for all customer correspondence.'
142
+ });
143
+ ```
144
+
145
+ ---
146
+
147
+ ## `searchAsync(pQuery)`
148
+
149
+ Runs a keyword search against the loaded corpus. Returns an array of `{ TopicKey, Title, Score, Snippet }`.
150
+
151
+ ```js
152
+ const tmpResults = await _Pict.views.InlineDocumentation.searchAsync('password reset');
153
+ tmpResults.forEach(r => console.log(r.Score.toFixed(2), r.TopicKey, r.Title));
154
+ ```
155
+
156
+ ---
157
+
158
+ ## `exportEditedTopicsAsync()`
159
+
160
+ In edit mode, returns every topic that has been modified in the running session so you can persist them or PR them back into the docs repo.
161
+
162
+ ```js
163
+ const tmpEdits = await _Pict.views.InlineDocumentation.exportEditedTopicsAsync();
164
+ await fetch('/api/docs/batch', { method: 'POST', body: JSON.stringify(tmpEdits) });
165
+ ```
166
+
167
+ ---
168
+
169
+ ## `on(pEventName, pHandler)` / `off(pEventName, pHandler)`
170
+
171
+ Emits lifecycle events:
172
+
173
+ - `topic-loaded` -- `{ TopicKey, Topic }`
174
+ - `topic-rendered` -- `{ TopicKey, Container }`
175
+ - `tooltip-shown` -- `{ Element, TopicKey }`
176
+ - `tooltip-hidden` -- `{ Element }`
177
+ - `catalog-loaded` -- `{ Catalog }`
178
+ - `topic-edited` -- `{ TopicKey, Topic }` (edit mode only)
179
+
180
+ ```js
181
+ _Pict.views.InlineDocumentation.on('topic-rendered', ({ TopicKey }) =>
182
+ {
183
+ _Pict.providers.Analytics.track('help:viewed', { topic: TopicKey });
184
+ });
185
+ ```
@@ -0,0 +1,103 @@
1
+ # Architecture
2
+
3
+ `pict-section-inlinedocumentation` is a Pict section that wraps three collaborating services: a **topic store**, a **renderer**, and a **binder**. The section itself is thin -- it owns configuration and lifecycle; the services do the work.
4
+
5
+ ## Core Concepts
6
+
7
+ - **Topic** -- a single Markdown file with frontmatter. Addressed by a slash-separated key such as `records/editing` or `customers/email-field`.
8
+ - **Catalog** -- a JSON index of topics, either shipped with the app or produced by `pict-docuserve prepare-docs`.
9
+ - **Route Map** -- a list of `{ Pattern, Topic }` entries that associates application routes with topic keys.
10
+ - **Binding** -- a runtime link between a DOM element and a topic, expressed via `data-help="<key>"` or via a Manyfest hash.
11
+
12
+ ## Component Diagram
13
+
14
+ ```mermaid
15
+ flowchart TB
16
+ subgraph Host["Host Pict Application"]
17
+ ROUTER[pict-router]
18
+ MANYFEST[Manyfest Descriptor]
19
+ DOM[DOM Controls]
20
+ end
21
+
22
+ subgraph Section["pict-section-inlinedocumentation"]
23
+ direction TB
24
+ CONFIG[Section Config]
25
+ STORE[TopicStore]
26
+ RENDER[TopicRenderer]
27
+ BINDER[TooltipBinder]
28
+ AUTOGEN[AutoTooltipGenerator]
29
+ SIDEBAR[SidebarView]
30
+ PANE[ReadingPaneView]
31
+ TOOLTIP[TooltipView]
32
+ CONFIG --> STORE
33
+ STORE --> RENDER
34
+ RENDER --> PANE
35
+ RENDER --> SIDEBAR
36
+ RENDER --> TOOLTIP
37
+ BINDER --> TOOLTIP
38
+ AUTOGEN --> BINDER
39
+ end
40
+
41
+ subgraph Sources["Content Sources"]
42
+ MD[(Markdown Files)]
43
+ CATALOG[(retold-catalog.json)]
44
+ KWIDX[(keyword-index.json)]
45
+ end
46
+
47
+ STORE -- fetch --> MD
48
+ STORE -- load --> CATALOG
49
+ STORE -- search --> KWIDX
50
+ ROUTER -- route change --> RENDER
51
+ MANYFEST -- hashes --> AUTOGEN
52
+ DOM -- data-help --> BINDER
53
+ BINDER -- hover/focus --> TOOLTIP
54
+ SIDEBAR --> DOM
55
+ PANE --> DOM
56
+ TOOLTIP --> DOM
57
+ ```
58
+
59
+ ## Services
60
+
61
+ ### TopicStore
62
+
63
+ Owns the corpus. Responsible for:
64
+
65
+ - Fetching the catalog on boot (or walking a folder if no catalog is provided).
66
+ - Lazy-loading individual topic Markdown on demand, with an LRU cache.
67
+ - Resolving aliases and redirects declared in topic frontmatter.
68
+ - Providing a keyword search API when `retold-keyword-index.json` is present.
69
+
70
+ ### TopicRenderer
71
+
72
+ Transforms topic Markdown into HTML and injects it into the reading pane or tooltip view. Supports:
73
+
74
+ - Frontmatter-driven title, category, and related-topic metadata.
75
+ - Mermaid, code-highlighting, and KaTeX passes (same as `pict-docuserve`).
76
+ - Template substitution for dynamic fields (e.g. the current entity name).
77
+
78
+ ### TooltipBinder
79
+
80
+ Manages the relationship between DOM elements and topics. It observes the document for elements with `data-help` attributes, attaches hover/focus listeners, and shows a small popover tooltip driven by `TopicRenderer`. Uses the Pict MutationObserver wrapper so dynamically added elements get picked up automatically.
81
+
82
+ ### AutoTooltipGenerator
83
+
84
+ Given a Manyfest descriptor, walks every hash in the descriptor and creates a synthetic topic key like `<manyfest-scope>/<hash>`. If a topic already exists, it is used as-is. If not, a stub is created in memory and -- in edit mode -- persisted back to the content service so an editor can fill it in from the running app.
85
+
86
+ ## Lifecycle
87
+
88
+ 1. **Bootstrap** -- The section registers with Pict and receives its config.
89
+ 2. **Catalog load** -- `TopicStore` fetches the catalog (or enumerates files).
90
+ 3. **Sidebar render** -- `SidebarView` renders the ToC from the catalog.
91
+ 4. **Route hook** -- If a route map is configured, the section subscribes to `pict-router` change events and asks `TopicRenderer` to render the current topic.
92
+ 5. **Tooltip binding** -- If `bindTooltipsAsync` has been called, every element in scope with `data-help` gets a tooltip.
93
+ 6. **Auto-generation** -- If `autoGenerateTooltipsAsync` has been called, the Manyfest hashes are walked and bindings applied.
94
+
95
+ ## Pict Content Assignment
96
+
97
+ The section honors the Pict `Pict-Content-Assignment` override pattern: rendering goes through the section's assigned content target, so it works in the browser, in blessed/terminal Pict apps via `pict-terminalui`, and in unit tests via `Pict-Environment-Log`.
98
+
99
+ ## Security
100
+
101
+ - Markdown is rendered with a safe allowlist; script tags and `javascript:` URLs are stripped.
102
+ - Topic keys are validated against `^[a-z0-9][a-z0-9/-]*$` before being used as URL paths.
103
+ - The optional edit-mode persistence path requires an explicit `EditEndpoint` and a bearer token; it will refuse to POST without both.