@nanisoft/prism-llms 0.5.0 → 0.5.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.
- package/dist/data.json +64 -22
- package/dist/extractor.js +42 -15
- package/dist/llms-full.txt +306 -26
- package/dist/llms.txt +4 -3
- package/dist/md/blocks/note-grid-01.md +0 -4
- package/dist/md/blocks/product-grid-01.md +0 -6
- package/dist/md/blocks/settings-panel-01.md +0 -2
- package/dist/md/blocks/site-header.md +0 -4
- package/dist/md/changelogs/prism-llms.md +38 -0
- package/dist/md/changelogs/prism-mcp-server.md +7 -0
- package/dist/md/changelogs/prism-ui.md +38 -0
- package/dist/md/components/product-mark.md +0 -9
- package/dist/md/components/select.md +1 -1
- package/dist/md/pages/docs-shell.md +218 -0
- package/dist/prism-skill.md +1 -1
- package/package.json +3 -3
|
@@ -1,5 +1,43 @@
|
|
|
1
1
|
# @nanisoft/prism-ui
|
|
2
2
|
|
|
3
|
+
## 0.7.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 5c43520: Add `DocsShell`, a documentation page that takes a site's navigation as data
|
|
8
|
+
|
|
9
|
+
`DocsShell` is a documentation screen: a navigation rail, the document, a
|
|
10
|
+
contents rail, and a pager to the neighbouring pages. It replaces the unstyled
|
|
11
|
+
`docs-shell` the retired line published, and it is the Page the three NaniSoft
|
|
12
|
+
product sites already import by that name.
|
|
13
|
+
|
|
14
|
+
The navigation is data. A tree of one page and a tree of twenty-seven render the
|
|
15
|
+
same way, at any depth, and the frame is sized by what the caller passed rather
|
|
16
|
+
than by a fixed arrangement, so three sites whose documentation sets differ in
|
|
17
|
+
shape share one Page with no per-site fork.
|
|
18
|
+
|
|
19
|
+
- `nav` and `toc` are closed unions of `page`, `group` and `divider`. Both are
|
|
20
|
+
read in the order given: nothing is sorted or alphabetised, so a site that
|
|
21
|
+
files its rail as a pipeline and its contents as a reference has both in one
|
|
22
|
+
render.
|
|
23
|
+
- The pager is derived from `nav` and `currentHref`. There is no `neighbours`
|
|
24
|
+
prop, so a neighbour that is not in the tree cannot be expressed, and each
|
|
25
|
+
consumer loses one derivation of its own.
|
|
26
|
+
- A group with no `href` renders a `span` rather than an anchor with no
|
|
27
|
+
destination. The three sites spell that case today as an empty string, and two
|
|
28
|
+
of them carry a stylesheet rule that styles the result back into a label; those
|
|
29
|
+
rules are now deletable.
|
|
30
|
+
- A section carries no status, no badge, no count, no collapse and no sort. A
|
|
31
|
+
status written into a title stays in the title as words.
|
|
32
|
+
- Both rails are bounded against the viewport, because one site's tree is half
|
|
33
|
+
again as tall as another's.
|
|
34
|
+
|
|
35
|
+
The corpus fix that shipped with it: the props extractor read each declaration
|
|
36
|
+
body twice with two depth counters that disagreed, so a Page whose `index.tsx`
|
|
37
|
+
re-exported a value and a type from one sibling published every prop twice and
|
|
38
|
+
swept the members of its navigation union into its own prop list. It now reads
|
|
39
|
+
each body once.
|
|
40
|
+
|
|
3
41
|
## 0.6.0
|
|
4
42
|
|
|
5
43
|
### Minor Changes
|
|
@@ -112,12 +112,3 @@ export default function ProductMarkDemo() {
|
|
|
112
112
|
**`pack`** `PackId | null` · optional · default: — — The product's pack, which is the mark's hue. Omit it, or pass `null`, for the one entry in a set that has no pack of its own: that entry is drawn as the full spectrum rather than as a colourless mark. See `SPECTRUM` above. `default` is a real answer and not the same as the empty one. The base pack is a pack a product can wear, and it is the absence of a `data-pack` attribute, so a product whose pack is `default` carries no attribute and its core resolves the base pack's `primary` from the page.
|
|
113
113
|
**`size`** `ProductMarkSize` · optional · default: `'md'` — Which of the three drawn sizes to use.
|
|
114
114
|
**`className`** `string` · optional · default: — — Layout only, exactly as on every Component. Changing a Prism-owned visual property from here is prohibited, and this Component spreads no other prop, so there is no second route to its ink.
|
|
115
|
-
**`stored`** `string | null` · required · default: — — Raw contents of the key this line writes, or `null` when it is absent.
|
|
116
|
-
**`legacy`** `string | null` · required · default: — — Raw contents of one key this line no longer writes, or `null`.
|
|
117
|
-
**`documentPack`** `string | null` · required · default: — — `data-pack` on the root element as rendered, valid or not.
|
|
118
|
-
**`documentDark`** `boolean` · required · default: — — Whether the root element carries `.dark` as rendered.
|
|
119
|
-
**`defaultPack`** `PackId` · required · default: —
|
|
120
|
-
**`defaultMode`** `Mode` · required · default: —
|
|
121
|
-
**`mode`** `Mode` · required · default: —
|
|
122
|
-
**`origin`** `ThemeOrigin` · required · default: — — Which source named the pair, for `THEME_ORIGIN_ATTRIBUTE`.
|
|
123
|
-
**`key`** `string` · required · default: —
|
|
@@ -142,9 +142,9 @@ export default function SelectDemo() {
|
|
|
142
142
|
**`items`** `Record<string, React.ReactNode> | ReadonlyArray<{ label: React.ReactNode; value: string; }>` · optional · default: — — The options, keyed by value, so the trigger can render a label before any item has mounted. Without it, `SelectValue` shows the raw value.
|
|
143
143
|
**`itemToStringLabel`** `(value: string) => string` · optional · default: — — Converts an item value to the label shown in the trigger.
|
|
144
144
|
**`children`** `React.ReactNode` · optional · default: — — The trigger and the popup content.
|
|
145
|
-
**`label`** `React.ReactNode` · required · default: —
|
|
146
145
|
**`size`** `'sm' | 'default'` · optional · default: `default` — The trigger's height.
|
|
147
146
|
**`placeholder`** `React.ReactNode` · optional · default: — — Shown when no value is selected.
|
|
148
147
|
**`side`** `'top' | 'right' | 'bottom' | 'left'` · optional · default: `bottom` — Which side of the trigger the list is placed on.
|
|
149
148
|
**`align`** `'start' | 'center' | 'end'` · optional · default: `center` — How the list aligns against the trigger.
|
|
150
149
|
**`sideOffset`** `number` · optional · default: `4` — The distance in pixels between the trigger and the list.
|
|
150
|
+
**`label`** `string` · optional · default: — — A text label used for keyboard typeahead when the option text differs.
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# DocsShell
|
|
2
|
+
|
|
3
|
+
A documentation screen: a navigation rail whose shape arrives as data, the document at the measure, a contents rail, and a pager derived from the navigation rather than passed.
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
import { DocsShell } from '@nanisoft/prism-ui/pages/docs-shell'
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
DocsShell is a documentation screen: a navigation rail, the document, a contents
|
|
12
|
+
rail, and the pager to the neighbouring pages.
|
|
13
|
+
|
|
14
|
+
**It is the Page the other three NaniSoft sites import, and the name is theirs.**
|
|
15
|
+
All three already read `import { DocsShell, type DocsNavEntry } from
|
|
16
|
+
'@nanisoft/prism-ui/pages'` in their own document template, and all three map
|
|
17
|
+
their page tree into that shape in their own `lib/to-prism-tree`. A published
|
|
18
|
+
name cannot be cheaply changed and there is no redirect lane for item routes, so
|
|
19
|
+
the name follows those three import lines rather than this file's shape. It was
|
|
20
|
+
`docs-shell` in the retired line too, where it was an empty `div` and a class
|
|
21
|
+
name each site then had to style from scratch.
|
|
22
|
+
|
|
23
|
+
**The shape arrives as data.** The three sites publish full documentation sets
|
|
24
|
+
and none of them agrees on the shape:
|
|
25
|
+
|
|
26
|
+
- Nexus files six sections of five pages, each named for a documentation genre,
|
|
27
|
+
each with an index.
|
|
28
|
+
- Atlas files four sections, one of which holds nine pages under a single
|
|
29
|
+
heading, and not one of them has an index.
|
|
30
|
+
- AlphaLens files six sections separated by rules, named for subject matter
|
|
31
|
+
rather than for a genre, with a status inside three of the titles.
|
|
32
|
+
|
|
33
|
+
The tree is a prop and the Page renders it, so none of the three had to be told
|
|
34
|
+
which of the others it looks like.
|
|
35
|
+
|
|
36
|
+
## Guidelines
|
|
37
|
+
|
|
38
|
+
### When to use
|
|
39
|
+
|
|
40
|
+
Use DocsShell as the body of the route that renders one documentation page,
|
|
41
|
+
handed the page tree, the document's own outline, and the address being rendered.
|
|
42
|
+
|
|
43
|
+
Use it for every page of a documentation set. A documentation site whose pages
|
|
44
|
+
each carry their own rail is a site whose rail drifts.
|
|
45
|
+
|
|
46
|
+
### When not to use
|
|
47
|
+
|
|
48
|
+
Do not use it for a single-page site. It is a whole screen around a tree, and a
|
|
49
|
+
site with one page has no tree.
|
|
50
|
+
|
|
51
|
+
Do not use it for a blog. A post is a dated argument about one thing, and
|
|
52
|
+
`BlogPostPage` is that screen.
|
|
53
|
+
|
|
54
|
+
Do not hand it a `nav` you built by parsing a folder tree at render time. Map
|
|
55
|
+
the tree once, in your own adapter, and pass the result: a Page that walked a
|
|
56
|
+
filesystem would be a Page that fetches, and a Page imports no router and no data
|
|
57
|
+
client.
|
|
58
|
+
|
|
59
|
+
### Best practices
|
|
60
|
+
|
|
61
|
+
- **A section is a label, not a control.** It carries no status, no badge, no
|
|
62
|
+
count, no collapse and no sort, and that is the whole of its interface. AlphaLens
|
|
63
|
+
files its documentation as a pipeline, where "Unified data contract (approved)"
|
|
64
|
+
is a stage of the work and not a topic a reader may visit in any order, and
|
|
65
|
+
every structural affordance says the opposite. A status in the title is part of
|
|
66
|
+
the title and stays there as words: the Page reads no parentheses, matches no
|
|
67
|
+
vocabulary, and renders no pill beside a heading that has one.
|
|
68
|
+
- **Omit `href` on a group that has no index.** That absence is what makes the
|
|
69
|
+
heading a label rather than a route, and it is the same thing all three sites
|
|
70
|
+
already spell as `url: node.index?.url ?? ''`, which two of them then restyle
|
|
71
|
+
back into a label in their own stylesheets. Naming the case in the type makes
|
|
72
|
+
those rules dead rather than load-bearing, and the type is the only thing that
|
|
73
|
+
had to change.
|
|
74
|
+
- **Do not pass a previous and a next.** The pager is derived from `nav` and
|
|
75
|
+
`currentHref`, which removes one derivation from every consumer. It is derived
|
|
76
|
+
rather than passed for a second reason: a caller who passes neighbours can pass
|
|
77
|
+
a neighbour that is not in the tree, and this is the one arrangement where a
|
|
78
|
+
reader would notice.
|
|
79
|
+
- **Give the rail and the contents their own orders, and let both stand.** `nav`
|
|
80
|
+
is in the order the rail shows and `toc` is in the order the contents rail
|
|
81
|
+
shows. Nothing is sorted, deduplicated or alphabetised. A site that files its
|
|
82
|
+
rail as a pipeline and its contents as a reference has both in one render.
|
|
83
|
+
- Pass `toc` whole or not at all. A partial outline is a contents list that lies
|
|
84
|
+
about the page.
|
|
85
|
+
- Omit `title` when your document owns its own heading. The Page renders no empty
|
|
86
|
+
`h1` to fill the gap, so a document with no title keeps exactly the outline its
|
|
87
|
+
own content declares.
|
|
88
|
+
- Name the three regions. `navLabel`, `tocLabel` and `pagerLabel` are required
|
|
89
|
+
because they are words a reader hears, and a Page that ships no copy ships no
|
|
90
|
+
reader-facing copy either. A site that files its pages as a pipeline and its
|
|
91
|
+
contents as a reference names the three regions three different ways.
|
|
92
|
+
|
|
93
|
+
### Content guidelines
|
|
94
|
+
|
|
95
|
+
- Put a section's stage in its title, as AlphaLens does, and let it stay a
|
|
96
|
+
sentence. The Page will not pull it out into a badge for you, and a badge is a
|
|
97
|
+
state the reader can act on, which a stage of a pipeline is not.
|
|
98
|
+
- Keep a rule's title short or leave it empty. A rule with words is a label a
|
|
99
|
+
reader reads twice: once in the rule and once on the section beneath it.
|
|
100
|
+
- Keep a section index page's title the same as its section's title, so a reader
|
|
101
|
+
who arrives at the index and a reader who is already inside the section are
|
|
102
|
+
reading the same words.
|
|
103
|
+
|
|
104
|
+
**A documentation screen: the rail, the document, the contents and the pager.**
|
|
105
|
+
|
|
106
|
+
```tsx
|
|
107
|
+
import { DocsShell, type DocsNavEntry } from '@nanisoft/prism-ui/pages/docs-shell'
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* The shape the three consumer sites actually publish, taken from AlphaLens
|
|
111
|
+
* because it is the one that exercises every part of the interface at once: a
|
|
112
|
+
* status inside a section title, a rule between sections, and a section whose
|
|
113
|
+
* own index is a page a reader lands on.
|
|
114
|
+
*/
|
|
115
|
+
const NAV: DocsNavEntry[] = [
|
|
116
|
+
{ type: 'page', title: 'AlphaLens', href: '#alphalens' },
|
|
117
|
+
{ type: 'divider', title: 'Data platform (live)' },
|
|
118
|
+
{
|
|
119
|
+
type: 'group',
|
|
120
|
+
title: 'Data platform (live)',
|
|
121
|
+
href: '#data-platform',
|
|
122
|
+
items: [
|
|
123
|
+
{ type: 'page', title: 'Capture', href: '#capture' },
|
|
124
|
+
{ type: 'page', title: 'Storage', href: '#storage' },
|
|
125
|
+
{ type: 'page', title: 'Operations', href: '#platform-operations' },
|
|
126
|
+
],
|
|
127
|
+
},
|
|
128
|
+
{ type: 'divider', title: 'Unified data contract (approved)' },
|
|
129
|
+
{
|
|
130
|
+
type: 'group',
|
|
131
|
+
title: 'Unified data contract (approved)',
|
|
132
|
+
href: '#data-contract',
|
|
133
|
+
items: [
|
|
134
|
+
{ type: 'page', title: 'Data feed view', href: '#feed-view' },
|
|
135
|
+
{ type: 'page', title: 'Timestamps and symbols', href: '#timestamps' },
|
|
136
|
+
],
|
|
137
|
+
},
|
|
138
|
+
{ type: 'divider', title: 'Research pipeline (designed)' },
|
|
139
|
+
{
|
|
140
|
+
// No `href`: this group is a label, because its folder holds no index page.
|
|
141
|
+
type: 'group',
|
|
142
|
+
title: 'Research pipeline (designed)',
|
|
143
|
+
items: [
|
|
144
|
+
{ type: 'page', title: 'Anatomy', href: '#anatomy' },
|
|
145
|
+
{ type: 'page', title: 'NSE portability', href: '#nse-portability' },
|
|
146
|
+
],
|
|
147
|
+
},
|
|
148
|
+
]
|
|
149
|
+
|
|
150
|
+
/** The headings inside this page. Your own pipeline knows them; Prism does not. */
|
|
151
|
+
const TOC: DocsNavEntry[] = [
|
|
152
|
+
{ type: 'page', title: 'The capture path', href: '#the-capture-path' },
|
|
153
|
+
{ type: 'page', title: 'What the store holds', href: '#what-the-store-holds' },
|
|
154
|
+
{ type: 'page', title: 'Where this is heading', href: '#where-this-is-heading' },
|
|
155
|
+
]
|
|
156
|
+
|
|
157
|
+
/** A documentation screen: the rail, the document, the contents and the pager. */
|
|
158
|
+
export default function DocsShellDemo() {
|
|
159
|
+
return (
|
|
160
|
+
<DocsShell
|
|
161
|
+
title="Storage"
|
|
162
|
+
description="Where a full chain of bars lands, and how it is partitioned."
|
|
163
|
+
nav={NAV}
|
|
164
|
+
toc={TOC}
|
|
165
|
+
currentHref="#storage"
|
|
166
|
+
navLabel="AlphaLens documentation"
|
|
167
|
+
tocLabel="On this page"
|
|
168
|
+
pagerLabel="AlphaLens pages"
|
|
169
|
+
pagerLabels={{ previous: 'Previous', next: 'Next' }}
|
|
170
|
+
>
|
|
171
|
+
<p>
|
|
172
|
+
The chain is written in columnar blocks, one per session per symbol, and
|
|
173
|
+
nothing is rewritten to correct it. What lands is what the exchange sent.
|
|
174
|
+
</p>
|
|
175
|
+
<h2 id="the-capture-path">The capture path</h2>
|
|
176
|
+
<p>
|
|
177
|
+
A capture is a session and a symbol, never a whole day. A day is a
|
|
178
|
+
partition over sessions, which is what makes a backtest cheap to repeat
|
|
179
|
+
and expensive to store twice.
|
|
180
|
+
</p>
|
|
181
|
+
<h2 id="what-the-store-holds">What the store holds</h2>
|
|
182
|
+
<ul>
|
|
183
|
+
<li>Every strike, call and put, at the exchange clock.</li>
|
|
184
|
+
<li>Open interest and the implied volatility of each strike.</li>
|
|
185
|
+
<li>The index future and the spot it settled against.</li>
|
|
186
|
+
</ul>
|
|
187
|
+
<h2 id="where-this-is-heading">Where this is heading</h2>
|
|
188
|
+
<p>
|
|
189
|
+
The same path, ported to .NET, is designed rather than built. The stage it
|
|
190
|
+
is at is in its title, because a stage of a pipeline is not a topic a
|
|
191
|
+
reader may visit in any order.
|
|
192
|
+
</p>
|
|
193
|
+
</DocsShell>
|
|
194
|
+
)
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Props
|
|
199
|
+
|
|
200
|
+
**`title`** `string` · optional · default: — — The page's title, and the document's `h1`. It is optional because the three consumer sites do not agree about whether a documentation page has one: two render the frontmatter title as the page heading, and one lets the document's own Markdown own it. When it is absent the Page renders no heading at all rather than an empty one, so the document keeps exactly the outline its own content declares.
|
|
201
|
+
**`description`** `ReactNode` · optional · default: — — One or two sentences under the title: what this part of the documentation covers. A `ReactNode` because a site that files a page for a pipeline states the pipeline's stage as markup rather than as a sentence.
|
|
202
|
+
**`nav`** `readonly DocsNavEntry[]` · optional · default: — — The documentation tree, in the order a reader should meet it. The whole shape arrives here, so the Page holds no opinion about how many sections a site has, how deep they nest, or what a section is called.
|
|
203
|
+
**`toc`** `readonly DocsNavEntry[]` · optional · default: — — The headings inside this page, in document order, for the contents rail. It is the consumer's document that knows its own outline, because Prism does not parse Markdown and a Page that guessed at it would guess wrong on every document rather than on some. Pass the whole outline or none: a partial one is a contents list that lies about the page.
|
|
204
|
+
**`currentHref`** `string` · optional · default: — — The address of the page being rendered. The rail marks it with `aria-current="page"` and the pager derives its two neighbours from it, so the same navigation renders a different pager for every page without the caller deriving anything.
|
|
205
|
+
**`navLabel`** `string` · required · default: — — The accessible name of the rail. Required whenever `nav` is passed, because it is a word a reader hears and a Page that ships no copy ships no reader-facing copy either.
|
|
206
|
+
**`tocLabel`** `string` · required · default: — — The accessible name of the contents rail. Required whenever `toc` is passed, for the same reason `navLabel` is.
|
|
207
|
+
**`pagerLabel`** `string` · required · default: — — The accessible name of the pager. Required whenever there is a neighbour to reach, for the same reason `navLabel` is.
|
|
208
|
+
**`pagerLabels`** `DocsPagerLabels` · required · default: — — The two words the pager renders above the neighbouring pages' titles. Required whenever either neighbour exists, for the same reason `navLabel` is.
|
|
209
|
+
**`children`** `ReactNode` · required · default: — — The document's own body. Any flow content: paragraphs, headings, lists, code, images, tables. `Prose` holds it to the reading measure and to the block rhythm, and it is passed `fullWidth` so the document fills the column the frame gives it rather than sitting in a second measure inside one.
|
|
210
|
+
**`header`** `ReactNode` · optional · default: — — A slot above the frame, inside the container: a breadcrumb trail, a version picker, a search field. A slot rather than a prop because each of those is a Block, and a Page that took one per prop would be a Page whose interface lists the whole catalogue.
|
|
211
|
+
**`footer`** `ReactNode` · optional · default: — — A slot below the frame, inside the container: a feedback prompt, a link back to the section index, a support address.
|
|
212
|
+
**`className`** `string` · optional · default: — — Layout only, exactly as on every Component. Changing a Prism-owned visual property from here is prohibited.
|
|
213
|
+
|
|
214
|
+
## Composition
|
|
215
|
+
|
|
216
|
+
**`exports`** `DocsShell` — the public runtime names this Page promises
|
|
217
|
+
**`source`** `packages/ui/src/pages/docs-shell/index.tsx` — the file this Page is defined in
|
|
218
|
+
**`dependencies`** `Prose` — the public Prism exports this item composes
|
package/dist/prism-skill.md
CHANGED
|
@@ -44,7 +44,7 @@ The read-only MCP endpoint is `https://prism.nanisoft.com/mcp`. It exposes nine
|
|
|
44
44
|
## This corpus
|
|
45
45
|
|
|
46
46
|
Generated from the catalogue and the authored pages: 34
|
|
47
|
-
Components, 19 Blocks and
|
|
47
|
+
Components, 19 Blocks and 7 Pages, plus the Overview,
|
|
48
48
|
Foundation, Content and Changelogs pages. The Changelogs pages are each
|
|
49
49
|
published package's own changelog, byte for byte; `get_changelog` returns one
|
|
50
50
|
package's, optionally one version of it.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nanisoft/prism-llms",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Prism's agent-facing corpus: llms.txt, the Markdown mirror, prism-skill.md and the PrismDocsStore projection. One build-fresh dist/ serves npm, the site and the MCP server.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
"@types/node": "^22.0.0",
|
|
39
39
|
"typescript": "^5.7.0",
|
|
40
40
|
"vitest": "^3.2.4",
|
|
41
|
-
"@nanisoft/prism-
|
|
42
|
-
"@nanisoft/prism-
|
|
41
|
+
"@nanisoft/prism-tokens": "0.6.0",
|
|
42
|
+
"@nanisoft/prism-ui": "0.7.0"
|
|
43
43
|
},
|
|
44
44
|
"scripts": {
|
|
45
45
|
"build": "node scripts/build.mjs",
|