@heroiclands/package-build 23.7.1 → 23.9.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 +41 -0
- package/README.md +32 -0
- package/bin/content-commands.mjs +32 -10
- package/ci/check-banners.mjs +37 -19
- package/container.mjs +48 -10
- package/docs/api.md +402 -58
- package/docs/authoring/first-note.md +1 -1
- package/docs/authoring/frontmatter.md +30 -1
- package/docs/authoring/links-and-markup.md +154 -56
- package/docs/commands.md +31 -12
- package/docs/content-format.md +25 -2
- package/docs/design.md +31 -0
- package/docs/diagnostics.md +1 -1
- package/docs/guides/e2e.md +37 -1
- package/docs/guides/packs.md +2 -1
- package/docs/guides/reference-pages.md +86 -63
- package/docs/project-setup.md +30 -15
- package/docs/reference/format-details.md +313 -132
- package/docs/reference/note-types.md +191 -174
- package/e2e.mjs +89 -2
- package/engine/anchors.mjs +7 -20
- package/engine/base-compiler.mjs +11 -18
- package/engine/compile-corpus.mjs +5 -3
- package/engine/content-alerts.mjs +4 -2
- package/engine/content-blocks.mjs +18 -36
- package/engine/content-format.yaml +1 -0
- package/engine/content-index.mjs +447 -33
- package/engine/content-links.mjs +43 -15
- package/engine/content-poetry.mjs +9 -0
- package/engine/content-tables.mjs +8 -4
- package/engine/culture-reach.mjs +61 -34
- package/engine/data-keys.mjs +3 -1
- package/engine/diagnostics.mjs +24 -11
- package/engine/dictionary-layout.mjs +151 -19
- package/engine/dictionary-rows.mjs +129 -79
- package/engine/foundry-entries.mjs +21 -3
- package/engine/frontmatter-lint.mjs +1 -1
- package/engine/generate.mjs +12 -22
- package/engine/glossary-entries.mjs +11 -11
- package/engine/heading-attributes.mjs +21 -28
- package/engine/helpers.mjs +20 -12
- package/engine/infobox.mjs +3 -0
- package/engine/journals.mjs +15 -2
- package/engine/language-data.mjs +53 -0
- package/engine/language-terms.mjs +86 -0
- package/engine/language-words.mjs +2 -2
- package/engine/lexical-sections.mjs +247 -0
- package/engine/markdownlint-run.mjs +12 -2
- package/engine/markup-validation.mjs +34 -0
- package/engine/note-addresses.mjs +1 -0
- package/engine/note-claims.mjs +21 -10
- package/engine/note-package.mjs +3 -5
- package/engine/note-state.mjs +9 -3
- package/engine/note-vocabulary.mjs +36 -7
- package/engine/pdf-build.mjs +17 -10
- package/engine/prose-lint.mjs +12 -6
- package/engine/related-pages.mjs +22 -3
- package/engine/see-also.mjs +150 -0
- package/engine/site-build.mjs +21 -3
- package/engine/site-preview.mjs +4 -2
- package/engine/sql-tables.mjs +287 -53
- package/engine/standings.mjs +14 -12
- package/engine/stub-lint.mjs +6 -2
- package/engine/web-wikilinks.mjs +8 -6
- package/engine/word-rows.mjs +20 -12
- package/engine/word-terms.mjs +15 -6
- package/hugo-theme/layouts/partials/related.html +25 -8
- package/package.json +2 -1
- package/types/container.d.mts +4 -3
- package/types/e2e.d.mts +28 -0
- package/types/engine/base-compiler.d.mts +2 -2
- package/types/engine/compile-corpus.d.mts +2 -1
- package/types/engine/content-index.d.mts +85 -8
- package/types/engine/content-tables.d.mts +2 -1
- package/types/engine/culture-reach.d.mts +22 -2
- package/types/engine/data-keys.d.mts +7 -0
- package/types/engine/diagnostics.d.mts +7 -6
- package/types/engine/dictionary-layout.d.mts +35 -4
- package/types/engine/dictionary-rows.d.mts +9 -0
- package/types/engine/foundry-entries.d.mts +3 -1
- package/types/engine/heading-attributes.d.mts +2 -2
- package/types/engine/helpers.d.mts +11 -5
- package/types/engine/language-terms.d.mts +7 -0
- package/types/engine/lexical-sections.d.mts +95 -0
- package/types/engine/markdownlint-run.d.mts +3 -1
- package/types/engine/markup-validation.d.mts +14 -0
- package/types/engine/note-addresses.d.mts +10 -0
- package/types/engine/note-claims.d.mts +7 -1
- package/types/engine/note-package.d.mts +3 -1
- package/types/engine/note-state.d.mts +2 -1
- package/types/engine/note-vocabulary.d.mts +1 -0
- package/types/engine/related-pages.d.mts +10 -1
- package/types/engine/see-also.d.mts +55 -0
- package/types/engine/site-build.d.mts +4 -1
- package/types/engine/sql-tables.d.mts +40 -6
- package/types/engine/word-rows.d.mts +9 -7
|
@@ -45,4 +45,4 @@ The full Address is `<package>-note-lore-harbor`; `<package>` comes from `conten
|
|
|
45
45
|
|
|
46
46
|
Add `description` for a short page summary, `tags: [draft]` to mark unfinished prose, or `data` for fields the note's type permits. A system block such as `sohl:` or `hm3:` adds mechanics and can produce a Foundry Actor or Item. It does not replace the shared prose or make another JournalEntry. [Frontmatter](frontmatter.md) explains the allowed keys, and the [note-type reference](../reference/note-types.md) lists every type-specific field.
|
|
47
47
|
|
|
48
|
-
Every typed note must have a nonempty body after its frontmatter. An empty or whitespace-only body is an error, even with `tags: [draft]` or a description.
|
|
48
|
+
Nonempty `data.words` on a language note, or `data.glossary` on a culture or affiliation, supplies content without an authored body. Every other typed note must have a nonempty body after its frontmatter, including folder and homepage notes. An empty or whitespace-only body is otherwise an error, even with `tags: [draft]` or a description. A nonempty body with fewer than 25 prose words produces a warning unless the note has a `draft` tag. A folder note needs only a nonempty body: any content passes, with or without the tag. See [note states](../reference/format-details.md#three-states-of-a-note).
|
|
@@ -31,7 +31,7 @@ The formatter keeps a collection on one line when the full line is under 100 cha
|
|
|
31
31
|
|
|
32
32
|
## Shared facts and game mechanics
|
|
33
33
|
|
|
34
|
-
The [note-type reference](../reference/note-types.md) lists every field accepted under `data`, including the shared `id`, `pack`, `packFolder`, `harnworld`, and `
|
|
34
|
+
The [note-type reference](../reference/note-types.md) lists every field accepted under `data`, including the shared `id`, `pack`, `packFolder`, `harnworld`, `banner`, and `seeAlso` fields. A type such as `being` also has its own fields, including `homes` and `affiliations`. `culture` is shared by `being`, `place`, `affiliation`, `lore` and `doc`: it names a `lore` note of `subType: culture`, is required on a `doc` of `subType: settingguide`, and is inherited down `data.parents` by places and affiliations. See [culture in the index](../reference/format-details.md#culture-in-the-index). A field absent from a type's vocabulary is a lint error; an unrelated field is not silently repurposed.
|
|
35
35
|
|
|
36
36
|
A being's `data.archetypes` names the roles it can fill in an adventure. Choose every specific role that fits, such as `entertainer` for a performer or `guildsperson` for someone whose professional training or connections matter. Use `[commoner]` when no specific archetype fits. `commoner` cannot share the list with another value. The [archetype reference](../reference/format-details.md#actors) defines the available roles.
|
|
37
37
|
|
|
@@ -41,6 +41,35 @@ A `sohl:`, `hm3:` or `dnd5e:` block holds values for that Foundry system. Its `s
|
|
|
41
41
|
|
|
42
42
|
One body describes the subject for both systems. A being's `{#appearance}` and `{#dossier}` sections feed SoHL Actor `system.appearance` and `system.dossier`, and HM3 Actor `system.description` and `system.biography`. An Item's `{#description}` page becomes a shared JournalEntryPage. Its resolved `@UUID[...]` pointer is stored in SoHL Item `system.docHtml` and HM3 Item `system.description`. An Item with no `{#description}` anchor uses its first page. Other H1 pages remain linkable.
|
|
43
43
|
|
|
44
|
+
## Suggested reading
|
|
45
|
+
|
|
46
|
+
Use `data.seeAlso` for deliberate cross-references. Each list entry has a required
|
|
47
|
+
`address` naming another note and an optional `gloss`: a short phrase explaining
|
|
48
|
+
why to follow it. The list keeps the order you write.
|
|
49
|
+
|
|
50
|
+
```yaml
|
|
51
|
+
data:
|
|
52
|
+
seeAlso:
|
|
53
|
+
- address: lore-harborhistory
|
|
54
|
+
gloss: The founding of the port
|
|
55
|
+
- address: place-breakwater
|
|
56
|
+
- address: thalorna-note-lore-searoutes
|
|
57
|
+
gloss: Routes beyond the bay
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Here the harbor history comes first, the breakwater needs no explanation, and
|
|
61
|
+
the sea routes belong to the declared `thalorna` dependency. Write bare Addresses,
|
|
62
|
+
without wikilink brackets or anchors; include the note type, since this field
|
|
63
|
+
has no default type. Local references default to this package and the `note`
|
|
64
|
+
system. A reference must resolve in this package or a declared dependency.
|
|
65
|
+
An unresolved address, duplicate destination, or reference to the note itself
|
|
66
|
+
is an error at that entry's address.
|
|
67
|
+
|
|
68
|
+
The website places these links and glosses in a **See also** group ahead of
|
|
69
|
+
inferred connections in **Related**. A destination also found among backlinks
|
|
70
|
+
or mentions appears only in See also. Foundry journals and books append a
|
|
71
|
+
**See also** section. An omitted or empty list adds no section or group.
|
|
72
|
+
|
|
44
73
|
## Place governments
|
|
45
74
|
|
|
46
75
|
A place may state its governing affiliation in `data.government`. The field type is `Address`, with `affiliation` as the default target type when the type is omitted. Use either a local shortcode or a fully qualified affiliation Address from this package or a fetched dependency:
|
|
@@ -178,6 +178,20 @@ The harbor master is working for the smugglers.
|
|
|
178
178
|
:::
|
|
179
179
|
```
|
|
180
180
|
|
|
181
|
+
Leave a blank line between a blockquote or alert and the closing `:::`. Without it, Markdown treats the fence as part of the quote and leaves the enclosing block unclosed:
|
|
182
|
+
|
|
183
|
+
```markdown
|
|
184
|
+
:::secret {title="For the GM"}
|
|
185
|
+
Hidden information.
|
|
186
|
+
|
|
187
|
+
> [!TIP]
|
|
188
|
+
> Advice for the GM.
|
|
189
|
+
|
|
190
|
+
:::
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
`lint`, `markdown` and `format` refuse malformed block and alert syntax, including unclosed divs and unknown alert types. `format` leaves a malformed file unchanged so you can correct the reported opening line before formatting it.
|
|
194
|
+
|
|
181
195
|
A secret block can contain alerts and general divs. It cannot contain another secret block. A heading that starts its own journal page cannot split a secret block or general div; use a lower heading without an anchor within the section.
|
|
182
196
|
|
|
183
197
|
Foundry renders a secret section; the website renders an expandable spoiler, and the book renders a labeled box. An untitled secret takes its normal default title, and a Foundry secret without an id receives an id derived from its body. The presentation does not make published HTML private: deliberately inspecting generated source can reveal its content. Use YAML comments for information that must never be published.
|
|
@@ -320,7 +334,7 @@ A column's heading is its SQL alias, so `AS "Name"` is what a reader sees. A cel
|
|
|
320
334
|
| `glossary` | One row per entry a culture or an affiliation writes in `data.glossary`, with the `note` it belongs to and the `language` it resolves to. |
|
|
321
335
|
| `language_lineage` | One row per language note and each language it inherits words from through `data.family`, itself included at `depth` 0. Join it to `words` for a language's words with inherited ones. |
|
|
322
336
|
| `dictionary` | One row per word per language it is listed under, inherited words included, with its `depth`. See [dictionaries and glossaries](#dictionaries-and-glossaries). |
|
|
323
|
-
| `terms` | One row per glossary entry, rank or office per note that owns it, with
|
|
337
|
+
| `terms` | One row per glossary entry, rank or office per note that owns it, with its `cultures` associations. See [dictionaries and glossaries](#dictionaries-and-glossaries). |
|
|
324
338
|
| `register` | One row per name a language note writes in `data.register`, with its `tongue`, `kind`, `gloss` and `why`, its pieces as `built_text`, and the `notes` carrying the name, derived from the index. |
|
|
325
339
|
| `tongues` | One row per tag a language note writes in `data.tongues`: `tag`, `meaning` and `tongue_language`. |
|
|
326
340
|
| `retired` | One row per form a language note writes in `data.retired`: `form`, `instead` as a list, and `why`. |
|
|
@@ -826,12 +840,12 @@ See [a language's register, sounds and history](../reference/format-details.md#a
|
|
|
826
840
|
|
|
827
841
|
A braced list may follow the language on the opening fence. Four attributes are accepted, and anything else is reported by name.
|
|
828
842
|
|
|
829
|
-
| Attribute | Value | Default | What it does
|
|
830
|
-
| --------------- | ----------------------------------- | ------- |
|
|
831
|
-
| `allow-empty` | `true` or `false` | `false` | Whether a query selecting no rows is allowed. A zero-row result is a finding otherwise, because a table that silently prints nothing is the commonest way a query goes wrong unnoticed.
|
|
832
|
-
| `section-level` | an integer from 1 through 6 | `2` | The heading level given to each group a `_section` column creates, and to each letter of a dictionary or a glossary.
|
|
833
|
-
| `key` | `true`, `false` or `only` | `true` | Whether a dictionary or a glossary prints its key. `false`
|
|
834
|
-
| `layout` | `table`, `dictionary` or `glossary` | `table` | How the result is set: as a table, as a dictionary of words, or as a glossary of terms — see [dictionaries and glossaries](#dictionaries-and-glossaries).
|
|
843
|
+
| Attribute | Value | Default | What it does |
|
|
844
|
+
| --------------- | ----------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
845
|
+
| `allow-empty` | `true` or `false` | `false` | Whether a query selecting no rows is allowed. A zero-row result is a finding otherwise, because a table that silently prints nothing is the commonest way a query goes wrong unnoticed. |
|
|
846
|
+
| `section-level` | an integer from 1 through 6 | `2` | The heading level given to each group a `_section` column creates, and to each letter of a dictionary or a glossary. |
|
|
847
|
+
| `key` | `true`, `false` or `only` | `true` | Whether a dictionary or a glossary prints its key. `false` omits the key and any dictionary verb table; `only` prints the key for the fence's rows and no table, letter or entry. Refused on a table. |
|
|
848
|
+
| `layout` | `table`, `dictionary` or `glossary` | `table` | How the result is set: as a table, as a dictionary of words, or as a glossary of terms — see [dictionaries and glossaries](#dictionaries-and-glossaries). |
|
|
835
849
|
|
|
836
850
|
````markdown
|
|
837
851
|
```sql {allow-empty=true section-level=3}
|
|
@@ -859,81 +873,165 @@ See [SQL details](../reference/format-details.md#content-tables) for query optio
|
|
|
859
873
|
|
|
860
874
|
### Dictionaries and glossaries
|
|
861
875
|
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
**The query decides what appears**, and any note may carry either fence. These are the common ones:
|
|
876
|
+
The build supplies a note's dictionary or glossary from its frontmatter on
|
|
877
|
+
every surface: the site, the Foundry journal and the book.
|
|
865
878
|
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
879
|
+
- **A language note with nonempty `data.words` receives a Dictionary section.** It
|
|
880
|
+
contains the language's full dictionary as one alphabetical list, with
|
|
881
|
+
letter headings, each word's field beside it and the key printed once. A
|
|
882
|
+
language with absent or empty `data.words` receives no Dictionary section.
|
|
883
|
+
- **A culture or affiliation with nonempty `data.glossary` receives a Glossary
|
|
884
|
+
section.** It contains only the entries that owner declares. Ranks and
|
|
885
|
+
offices stand in the affiliation's own sections; they enter its glossary
|
|
886
|
+
only when an explicit glossary entry names them. A note with absent or
|
|
887
|
+
empty `data.glossary` receives no Glossary section.
|
|
874
888
|
|
|
875
|
-
|
|
889
|
+
The sections follow the note's authored text. An existing heading with
|
|
890
|
+
`{#dictionary}` or `{#lexicon}` receives the dictionary after its authored
|
|
891
|
+
text; `{#glossary}` does the same for a glossary. The heading and its
|
|
892
|
+
introduction stay in place, with one generated list under it:
|
|
876
893
|
|
|
877
|
-
|
|
894
|
+
```markdown
|
|
895
|
+
## Lexicon {#lexicon}
|
|
896
|
+
|
|
897
|
+
The tongue of Provenzia, whose _solmère_ is its own word.
|
|
898
|
+
```
|
|
899
|
+
|
|
900
|
+
A dictionary belongs to a language; a glossary belongs to one culture or
|
|
901
|
+
affiliation. A glossary entry belongs for one of three reasons: a common word
|
|
902
|
+
in the owner's core vocabulary, a dictionary word with a context meaning,
|
|
903
|
+
or a phrase, compound or term of art outside the dictionary with its own
|
|
904
|
+
gloss. The [worked culture glossary](../reference/format-details.md#glossary-terms)
|
|
905
|
+
selects `solmère` as a common word, gives `amère` a context meaning and glosses
|
|
906
|
+
`blood-field` as a term outside the dictionary. Its frontmatter supplies the
|
|
907
|
+
whole default Glossary section. There are no setting-wide dictionary or
|
|
908
|
+
glossary pages.
|
|
909
|
+
|
|
910
|
+
A dictionary noun prints its gender from its existing class and its plural
|
|
911
|
+
where one is available: **marendos** _n. m., pl. marendoi_. An explicit
|
|
912
|
+
word plural wins; otherwise the language's optional `grammar.plural` rule
|
|
913
|
+
replaces the first matching literal ending. The language's optional
|
|
914
|
+
`grammar.verbs` pattern prints once as a small head table, after the key and
|
|
915
|
+
before the letters. Empty verb endings print as "unchanged". Grammar is
|
|
916
|
+
never inherited through `family`, and absent grammar leaves the dictionary
|
|
917
|
+
unchanged. The [worked noun and verb example](../reference/format-details.md#optional-noun-and-verb-forms)
|
|
918
|
+
shows both declarations. Only supplied shapes are checked; words are never
|
|
919
|
+
checked against the rule, and no language must state grammar.
|
|
920
|
+
|
|
921
|
+
An entry naming a word of its resolved language without a `definition`
|
|
922
|
+
carries the word's dictionary senses and class, with a link to the word's
|
|
923
|
+
entry on its language page. An entry with a `definition` carries that meaning
|
|
924
|
+
instead, retaining its word link and class when it names a dictionary word.
|
|
925
|
+
Ranks, offices and definitions carry their source body or culture beside
|
|
926
|
+
their senses. Common choices belong to each owner: a culture and an
|
|
927
|
+
affiliation using the same language choose independently, and a word may be
|
|
928
|
+
common in one glossary and absent from another. Dictionaries mark nothing
|
|
929
|
+
common.
|
|
930
|
+
|
|
931
|
+
Public dictionaries omit citations to GM-only notes. `links` checks generated
|
|
932
|
+
tables in the source note's audience: public notes use public rows, and GM
|
|
933
|
+
notes retain GM citations. An authored link from a public note to a GM-only
|
|
934
|
+
note is still reported.
|
|
935
|
+
|
|
936
|
+
#### Custom views
|
|
937
|
+
|
|
938
|
+
An `sql` fence with `layout=dictionary` or `layout=glossary` sets a custom view
|
|
939
|
+
of the same relations. A dictionary view reads `dictionary`; a glossary view
|
|
940
|
+
reads `terms`. Each needs the `name`, `senses` and `usage` columns; a query
|
|
941
|
+
that leaves one out is reported, naming the column.
|
|
942
|
+
|
|
943
|
+
The optional `plural` and `verbs` columns supply noun plurals and the head
|
|
944
|
+
table in a custom dictionary view; `SELECT *` includes both. A projection
|
|
945
|
+
that omits these columns omits that presentation, as omitting `class` omits
|
|
946
|
+
word classes. With the default or `key=true`, each selected language's pattern
|
|
947
|
+
appears once per dictionary result, even when no abbreviation key is needed.
|
|
948
|
+
`key=false` omits both the key and the verb table from a fragment;
|
|
949
|
+
`key=only` prints only the abbreviation key. Separate head-enabled fences
|
|
950
|
+
each print their own tables.
|
|
951
|
+
|
|
952
|
+
For a custom list of one culture's common entries:
|
|
878
953
|
|
|
879
954
|
````markdown
|
|
880
955
|
## Words Everyone Knows {#common-words}
|
|
881
956
|
|
|
882
|
-
```sql {layout=dictionary section-level=3}
|
|
883
|
-
SELECT * FROM dictionary WHERE language = 'thalorna-note-skill-vylarilng' AND common
|
|
884
|
-
```
|
|
885
|
-
````
|
|
886
|
-
|
|
887
|
-
A culture's glossary:
|
|
888
|
-
|
|
889
|
-
````markdown
|
|
890
|
-
## Glossary {#glossary}
|
|
891
|
-
|
|
892
957
|
```sql {layout=glossary section-level=3}
|
|
893
|
-
SELECT * FROM terms WHERE
|
|
958
|
+
SELECT * FROM terms WHERE owner = 'thalorna-note-lore-provenzianclt' AND common
|
|
894
959
|
```
|
|
895
960
|
````
|
|
896
961
|
|
|
897
|
-
A
|
|
962
|
+
A custom dictionary view can select one field from the language's dictionary:
|
|
898
963
|
|
|
899
964
|
````markdown
|
|
900
|
-
##
|
|
901
|
-
|
|
902
|
-
```sql {layout=dictionary key=only}
|
|
903
|
-
SELECT * FROM dictionary WHERE language = 'thalorna-note-skill-vylarilng' AND depth = 0
|
|
904
|
-
```
|
|
905
|
-
|
|
906
|
-
### Love and its conduct
|
|
965
|
+
## Love and its conduct
|
|
907
966
|
|
|
908
|
-
```sql {layout=dictionary
|
|
909
|
-
SELECT
|
|
910
|
-
WHERE
|
|
967
|
+
```sql {layout=dictionary section-level=3}
|
|
968
|
+
SELECT * FROM dictionary
|
|
969
|
+
WHERE language = 'thalorna-note-skill-provnzlng' AND field = 'Love and its conduct'
|
|
911
970
|
```
|
|
912
971
|
````
|
|
913
972
|
|
|
914
|
-
|
|
973
|
+
A custom view with several fences can print its key once: a `key=only` fence
|
|
974
|
+
over all selected rows, then `key=false` on each fence below it. The
|
|
975
|
+
`key=only` fence prints only the abbreviation key. `key`, whatever its value,
|
|
976
|
+
is refused on a fence set as a table. The automatic Dictionary section
|
|
977
|
+
prints its own key once for the full alphabetical list.
|
|
915
978
|
|
|
916
979
|
Either layout prints, in order:
|
|
917
980
|
|
|
918
|
-
- **a key**, once, unless the fence sets `key=false`, and nothing else where
|
|
919
|
-
|
|
920
|
-
|
|
981
|
+
- **a key**, once, unless the fence sets `key=false`, and nothing else where
|
|
982
|
+
it sets `key=only`, listing the abbreviations the result uses — a language's
|
|
983
|
+
tag, a word's class or a modifier — each with its expansion; a glossary also
|
|
984
|
+
explains the common mark where an entry carries it;
|
|
985
|
+
- **a heading per letter**, at `section-level`, accents taken off and
|
|
986
|
+
apostrophes skipped, so `'ostal` files under O and `Écuyer` under E;
|
|
987
|
+
- **one paragraph per entry**: a glossary's `•` for a common entry, the
|
|
988
|
+
headword in bold, its pronunciation between slashes, its language tag and
|
|
989
|
+
word class in italics where present, its senses, and after a dash the notes
|
|
990
|
+
it is cited from, as links.
|
|
921
991
|
|
|
922
|
-
A
|
|
992
|
+
A dictionary entry gives its field in italic parentheses and its etymology
|
|
993
|
+
in brackets:
|
|
923
994
|
|
|
924
995
|
```markdown
|
|
925
|
-
|
|
996
|
+
**solmère** /sol-MEH-reh/ _n. m._ (_Love and its conduct_) [fr. Élav. _sólmerë_] Longing; the ache for a person, a place or a time that is gone. — [[thalorna-note-lore-lastshrine|The Song of the Last Shrine]]
|
|
926
997
|
```
|
|
927
998
|
|
|
928
|
-
A
|
|
999
|
+
A glossary entry naming a dictionary word uses the word's senses when
|
|
1000
|
+
`definition` is absent; a list of dictionary glosses supplies every sense.
|
|
1001
|
+
Those senses carry no body label. An entry with a `definition` uses that
|
|
1002
|
+
meaning and labels it with the owner, retaining its word link and class
|
|
1003
|
+
where it names a dictionary word. On the owner's own page, a sense attributed
|
|
1004
|
+
only to that owner omits the repeated label; other bodies and shared senses
|
|
1005
|
+
keep their labels. A glossary sets the rows sharing a headword
|
|
1006
|
+
and a language as one entry, numbering their senses in query order and
|
|
1007
|
+
printing a sense several bodies give once, with all of them:
|
|
929
1008
|
|
|
930
1009
|
```markdown
|
|
931
|
-
**Sworn Knight** **1** (_Duchy of Aubrac_) Holds land of the duke. **2** (_Kingdom of Provenzia_) Holds land of the crown. **3**
|
|
932
|
-
```
|
|
933
|
-
|
|
934
|
-
The
|
|
935
|
-
|
|
936
|
-
|
|
1010
|
+
**Sworn Knight** **1** (_Duchy of Aubrac_) Holds land of the duke. **2** (_Kingdom of Provenzia_) Holds land of the crown. **3** A knight bound by oath to a lord. — [[thalorna-note-affiliation-duchy|Duchy of Aubrac]], [[thalorna-note-affiliation-kingdom|Kingdom of Provenzia]], [[thalorna-note-lore-provenzianclt|Provenzia]]
|
|
1011
|
+
```
|
|
1012
|
+
|
|
1013
|
+
The layout orders entries by letter, then by `name_sort`. **The language tag
|
|
1014
|
+
prints where the entry's language is not the page's own**: a language note's
|
|
1015
|
+
own language, a culture's `data.language`, or the language an affiliation's
|
|
1016
|
+
glossary resolves to. It is the language note's `data.abbreviation`, or its
|
|
1017
|
+
full name where unstated. Etymology never repeats the entry's own language:
|
|
1018
|
+
a borrowed word prints `[fr. Élav. _sólmerë_]`, a built word its pieces each
|
|
1019
|
+
with its gloss, `[_am-_ "love" + _-ère_ "one who"]`, an inherited word its
|
|
1020
|
+
older form, `[*_hur_]` or `[Hel. *_thalass_]`, and a root word its root and
|
|
1021
|
+
pattern. A citation of a note with no published page prints as its name.
|
|
1022
|
+
|
|
1023
|
+
A built piece can name a language element by its `form` or one of its
|
|
1024
|
+
`variants`; its `sense` prints beside the piece. An affix can also be named by
|
|
1025
|
+
its `front` form. Words and affixes take precedence over elements in the same
|
|
1026
|
+
language, and the language is searched before its ancestors. Exact spellings
|
|
1027
|
+
are checked before ignoring joining hyphens; case and accents are preserved.
|
|
1028
|
+
|
|
1029
|
+
A glossary entry may give its own sort key or respelling. A reference to a
|
|
1030
|
+
rank or office inherits its descriptions and admits a title of one word; its
|
|
1031
|
+
`common` value belongs to the entry's owner. A definition replaces the senses
|
|
1032
|
+
of the owner's own rank or office, or supplies an entry of the owner's own.
|
|
1033
|
+
The [format reference](../reference/format-details.md#dictionaries-and-glossaries)
|
|
1034
|
+
gives every column and rule.
|
|
937
1035
|
|
|
938
1036
|
## Page lists
|
|
939
1037
|
|
|
@@ -973,7 +1071,7 @@ That list names the `lore` notes tagged `key-concept`, grouped by type and alpha
|
|
|
973
1071
|
|
|
974
1072
|
**A tag no page carries is a finding** at the fence's own line, naming the tag it looked for. A misspelled tag is the whole of what goes wrong here, and a heading with an empty list under it is how one goes unnoticed. Write `{allow-empty=true}` where a group that is genuinely empty is intended; the directive then leaves nothing behind rather than an empty list.
|
|
975
1073
|
|
|
976
|
-
A page list names this package's own pages. A **stub** — a note with an
|
|
1074
|
+
A page list names this package's own pages. A **stub** — a note with neither an authored body nor automatic lexical content — publishes no page, so it joins no list. A note tagged `gm` is listed in Foundry and left out of the website and the book, exactly as it is left out of a content table's relations.
|
|
977
1075
|
|
|
978
1076
|
See [page-list details](../reference/format-details.md#page-lists) for the directive's full behaviour.
|
|
979
1077
|
|
package/docs/commands.md
CHANGED
|
@@ -1995,8 +1995,8 @@ package-build lint [root] [--no-references]
|
|
|
1995
1995
|
**DESCRIPTION**
|
|
1996
1996
|
|
|
1997
1997
|
Checks a content tree's addresses and frontmatter without compiling anything
|
|
1998
|
-
— no LevelDB is opened and no Foundry manifest is needed
|
|
1999
|
-
|
|
1998
|
+
— no LevelDB is opened and no Foundry manifest is needed. Beyond address
|
|
1999
|
+
well-formedness, it
|
|
2000
2000
|
checks frontmatter against the declared vocabulary and each system's `sohl:`
|
|
2001
2001
|
/ `hm3:` block, the package's charset (so a book can pick a font that covers
|
|
2002
2002
|
it), that an icon a note writes is one the registry declares, and that
|
|
@@ -2012,6 +2012,16 @@ dependencies; exact Item UUID validation remains part of compilation. Reads
|
|
|
2012
2012
|
the content tree named by `root`, defaulting to
|
|
2013
2013
|
`paths.content`; writes nothing.
|
|
2014
2014
|
|
|
2015
|
+
Content lint computes source positions when it emits findings and shares each
|
|
2016
|
+
note's YAML position document across consecutive lookups.
|
|
2017
|
+
|
|
2018
|
+
The final summary reports wall time in milliseconds for `index` (collecting
|
|
2019
|
+
content records), `SQL` (opening relations and preparing tables, inline queries
|
|
2020
|
+
and generated sections), and `validation` (building the link index and running
|
|
2021
|
+
the checks). These are elapsed durations from a monotonic clock, including any
|
|
2022
|
+
waits within each stage. They are prose summary output, separate from positioned
|
|
2023
|
+
findings, and appear whether completed validation passes or reports errors.
|
|
2024
|
+
|
|
2015
2025
|
**OPTIONS**
|
|
2016
2026
|
|
|
2017
2027
|
| Positional | Type | Default | Description |
|
|
@@ -2172,6 +2182,9 @@ wikilink at all. Also reports a vendored foreign-package content index that
|
|
|
2172
2182
|
has drifted out of reach, naming `package-build deps fetch` as the fix. Resolves
|
|
2173
2183
|
address-valued SoHL system fields declared by the installed schema against this
|
|
2174
2184
|
package and its declared dependencies.
|
|
2185
|
+
An anchored reference to a dependency's readable note must name a prose anchor
|
|
2186
|
+
in its fetched content index. A missing section is an error even when the page
|
|
2187
|
+
address resolves. Event ids are not prose sections and cannot be wikilink targets.
|
|
2175
2188
|
Reads the content tree named by `root`, defaulting to `paths.content`, and
|
|
2176
2189
|
the cached content indexes of any declared dependency; writes nothing.
|
|
2177
2190
|
|
|
@@ -2332,16 +2345,22 @@ package-build content-index [root] [--out <dir>]
|
|
|
2332
2345
|
|
|
2333
2346
|
**DESCRIPTION**
|
|
2334
2347
|
|
|
2335
|
-
Emits this package's note index as JSON Lines
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2348
|
+
Emits this package's note index as JSON Lines, carrying full frontmatter,
|
|
2349
|
+
tree positions, prose and event anchors, and document targets. Reads the
|
|
2350
|
+
content tree named by `root`, defaulting to `paths.content`; writes
|
|
2351
|
+
`<contentPackage>-metadata.jsonl`, `<contentPackage>-dictionary.jsonl` and
|
|
2352
|
+
`<contentPackage>-terms.jsonl` into `--out`, defaulting to the configured
|
|
2353
|
+
`paths.contentIndex`.
|
|
2354
|
+
|
|
2355
|
+
The command prepares SQL tables, page lists, automatic sections and scalar
|
|
2356
|
+
expressions before publishing their prose targets. Each source uses its own
|
|
2357
|
+
audience for prose declarations: public notes use public providers and usage,
|
|
2358
|
+
and GM notes use the complete corpus. Native target maps use the compendium's
|
|
2359
|
+
complete SQL corpus and expose only declared prose slugs present there, with
|
|
2360
|
+
their actual native page targets. Readable item documentation targets its
|
|
2361
|
+
documentation journal. An empty published prose-anchor list declares no prose targets,
|
|
2362
|
+
including for pages without a Foundry document. Preparation errors leave all
|
|
2363
|
+
three output files untouched.
|
|
2345
2364
|
|
|
2346
2365
|
**OPTIONS**
|
|
2347
2366
|
|
package/docs/content-format.md
CHANGED
|
@@ -9,7 +9,7 @@ subType: userguide
|
|
|
9
9
|
|
|
10
10
|
A content package begins with Markdown notes under `assets/content/`. Each note has YAML frontmatter describing its identity and data, followed by prose. Folder names beneath `assets/content/` are for authors; `type`, `subType`, and Addresses determine what the build creates.
|
|
11
11
|
|
|
12
|
-
Every typed note requires a nonempty body, including drafts, folders and homepages. An empty or whitespace-only body is an error. A nonempty body with fewer than 25 prose words warns unless tagged `draft`; the tag never exempts an empty body. A `folder` note needs only a nonempty body: any content passes, with or without `draft`.
|
|
12
|
+
Nonempty `data.words` on a language note (`type: skill`, `subType: language`), or `data.glossary` on a culture or affiliation, supplies page content without an authored body. Every other typed note requires a nonempty body, including drafts, folders and homepages. An empty or whitespace-only body is otherwise an error. A nonempty body with fewer than 25 prose words warns unless tagged `draft`; the tag never exempts an empty body. A `folder` note needs only a nonempty body: any content passes, with or without `draft`.
|
|
13
13
|
|
|
14
14
|
Start with [your first note](authoring/first-note.md). It explains the smallest valid note and shows the JournalEntry, web page, book entry, and content-index record made from it. Then use the chapters below in the order your note needs them.
|
|
15
15
|
|
|
@@ -91,6 +91,29 @@ errors, reported at the `ranks` key.
|
|
|
91
91
|
|
|
92
92
|
An Item's `{#description}` page is its readable description. The note Address `<package>-note-<type>-<shortcode>#description` resolves to a JournalEntryPage UUID. The build writes the same `@UUID[...]` pointer to SoHL Item `system.docHtml` and HM3 Item `system.description`. An Item note without that anchor uses its first page as the description. Other pages and anchors remain available for links.
|
|
93
93
|
|
|
94
|
+
## Suggesting another note
|
|
95
|
+
|
|
96
|
+
State deliberate cross-references in `data.seeAlso`, in reading order:
|
|
97
|
+
|
|
98
|
+
```yaml
|
|
99
|
+
data:
|
|
100
|
+
seeAlso:
|
|
101
|
+
- address: lore-harborhistory
|
|
102
|
+
gloss: The founding of the port
|
|
103
|
+
- address: place-breakwater
|
|
104
|
+
- address: thalorna-note-lore-searoutes
|
|
105
|
+
gloss: Routes beyond the bay
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Each `address` names a whole note; `gloss` optionally explains why to read it.
|
|
109
|
+
The first entry points to the port's history, the second to its breakwater,
|
|
110
|
+
and the third to a note in the declared `thalorna` dependency. An address must
|
|
111
|
+
resolve, and neither a duplicate destination nor the note itself is allowed.
|
|
112
|
+
The site shows the list ahead of other Related links, without repeating their
|
|
113
|
+
destinations. Journals and books append See also; an omitted or empty list adds
|
|
114
|
+
nothing. See [suggested reading](authoring/frontmatter.md#suggested-reading)
|
|
115
|
+
for the Address rules.
|
|
116
|
+
|
|
94
117
|
## File and folder names
|
|
95
118
|
|
|
96
119
|
Every character in the path of a content file or a picture is printable 7-bit ASCII, U+0020 to U+007E. The rule covers each file and folder name under the content tree and under the package's `icons/` and `images/` roots. Letters, digits, spaces, hyphens, underscores, dots and apostrophes are all inside it, so `Knight's_Shield.md` is a valid name. An accented letter, any other non-ASCII character, and a control character are outside it.
|
|
@@ -143,6 +166,6 @@ Places, affiliations, lore and beings may name their culture in `data.culture`,
|
|
|
143
166
|
|
|
144
167
|
An affiliation may name the trade, temple or order tongue it keeps in its own `data.language`. An affiliation that reaches no culture is a warning, in a tree holding a culture note. A language needs no culture and no affiliation. See [type: affiliation](reference/format-details.md#type-affiliation).
|
|
145
168
|
|
|
146
|
-
A language note (`type: skill`, `subType: language`) states its words in frontmatter: `data.words` states each word as a map of its form, class, field and gloss — one sense or a list of them, which a dictionary numbers — with its source, its variant forms, the pieces it is built from and a note, beside `data.classModifiers`, `data.fields` and `data.affixes`, each affix with the `kind` it makes, for a given name's ending who the name is `given` to, and the stem closes it is barred after; a zero affix states `zero: true` and no form. The notes a word is cited from are derived, not written: a note cites a word by marking it in italics in its prose, matched by form or a variant with diacritics and case set aside. The language of a word is the note it sits on, and none of it reaches the compiled Item. A daughter language names its parent in `data.family` and reads the parent's words as its own; the `language_lineage` relation joins a language to its ancestors. Classes come from the [master word classes](reference/format-details.md#word-classes). A culture or an affiliation states its own glossary
|
|
169
|
+
A language note (`type: skill`, `subType: language`) states its words in frontmatter: `data.words` states each word as a map of its form, class, field and gloss — one sense or a list of them, which a dictionary numbers — with its source, its variant forms, the pieces it is built from and a note, beside `data.classModifiers`, `data.fields` and `data.affixes`, each affix with the `kind` it makes, for a given name's ending who the name is `given` to, and the stem closes it is barred after; a zero affix states `zero: true` and no form. The notes a word is cited from are derived, not written: a note cites a word by marking it in italics in its prose, matched by form or a variant with diacritics and case set aside. The language of a word is the note it sits on, and none of it reaches the compiled Item. A daughter language names its parent in `data.family` and reads the parent's words as its own; the `language_lineage` relation joins a language to its ancestors. Classes come from the [master word classes](reference/format-details.md#word-classes). A culture or an affiliation states its own glossary entries in `data.glossary`: common words in its core vocabulary, dictionary words with a context meaning, or phrases, compounds and terms of art outside the dictionary with their own gloss. An entry naming a word of its resolved language takes the word's senses and class and links to its language entry; a `definition` supplies the entry's meaning instead. Common marks belong to the glossary's owner. A language note with nonempty `data.words` receives its full Dictionary section automatically: one alphabetical list with field tags and one key. A culture or affiliation with nonempty `data.glossary` receives only its explicitly declared entries in its Glossary section; ranks and offices stand in the affiliation's own sections. A note without the relevant frontmatter receives no such section. All surfaces show these sections after the authored text, or under an existing `{#dictionary}`, `{#lexicon}` or `{#glossary}` heading after its introduction. There are no setting-wide dictionary or glossary pages. Every entry resolves to a language — its own `language`, else the affiliation's, its parents' or its culture's, else the culture's — or is an error at the entry. The `words`, `affixes`, `fields`, `glossary` and `language_lineage` relations hold them for `sql` fences, the `dictionary` relation lists each word under every language that has it, inherited words included, and the `terms` relation each glossary entry, rank and office with its culture associations; a fence sets custom views with `layout=dictionary` or `layout=glossary`. A language note names the tag a dictionary prints for it in `data.abbreviation`. Every fact a check reads about a language's names, sounds and history is frontmatter too: `data.tongues` and `data.register` (every name the setting gives in the language's reach, the notes carrying each derived from the index), `data.retired`, `data.scope`, `data.sounds` (letters with their place, word edges from a closed list, the cluster limit and the groups of clusters inside a word, the stress rule, syllable finals, syllable rules and vowel harmony with each vowel's front partner, the joining of parts, written marks, a root's skeleton vowel and frames, the spellings read past, and named mutations such as wearing and voicing), `data.soundChanges` (named sets of ordered steps), `data.elements` (each standing `opening`, `closing`, `either` or `link`, for one kind of name, with the word it is the stem of and its genitive), `data.roots`, `data.cognates` (with a reconstructed `proto` form), `data.callingNames`, `data.older` (the forms older than the rules), `data.negation` (the negative particle and the mutation it brings) and `data.naming` (how long each class of name runs, the edges names keep that words do not, the element kinds each kind of name draws on, what a place name takes from what it is held from, and the near name), each a relation — `sounds` as `letters`, `edges`, `clusters`, `cluster_groups`, `stress`, `finals`, `syllables`, `joining`, `joins`, `marks`, `skeleton`, `frames`, `read_past` and `mutations`, `soundChanges` as `sound_changes`, `callingNames` as `calling_names` — that a fence sets back on the page. A word's citations also come from a note whose name, alias or rank or office title spells it whole. See [a language's words](reference/format-details.md#a-languages-words), [a language's register, sounds and history](reference/format-details.md#a-languages-register-sounds-and-history), [glossary terms](reference/format-details.md#glossary-terms) and [dictionaries and glossaries](reference/format-details.md#dictionaries-and-glossaries).
|
|
147
170
|
|
|
148
171
|
Blockquote alerts use `[!NOTE]`, `[!TIP]`, `[!IMPORTANT]`, `[!WARNING]`, or `[!]`, with optional attributes after the marker. They replace the former info and warn div fences; secret blocks remain supported. See [alerts](authoring/links-and-markup.md#alerts).
|
package/docs/design.md
CHANGED
|
@@ -30,3 +30,34 @@ Passes declare their inputs and outputs so compile order follows dependencies wh
|
|
|
30
30
|
## Verification
|
|
31
31
|
|
|
32
32
|
The command and API references have tests that derive their surfaces from source. The note-format contract lives in structured data and code declarations so editorial changes to Markdown do not change validation. Generated field references are checked against those declarations. Tests check emitted documents as well as input acceptance: a build that exits successfully but drops a value is still wrong. A consumer regression run compares `build/packs-json` across toolchain versions against a real content tree.
|
|
33
|
+
|
|
34
|
+
The SQL scaling guard runs `prepareTreeSqlTables` over two sizes of a synthetic
|
|
35
|
+
linked note tree, with rewritten shortcodes and references. It profiles each
|
|
36
|
+
executed query through the supplied database, including local and dependency
|
|
37
|
+
relations, inline expressions and generated event sections. DuckDB's JSON
|
|
38
|
+
`EXPLAIN ANALYZE` reports the actual cardinality of file-reader operators before
|
|
39
|
+
downstream filters; these source rows must stay at zero after database creation.
|
|
40
|
+
A direct JSON scan is the positive control for that measurement. In-memory
|
|
41
|
+
scans may grow with the corpus, and elapsed time is not an assertion. Schema
|
|
42
|
+
inspection through `DESCRIBE` has no execution profile and is excluded.
|
|
43
|
+
|
|
44
|
+
Run the guard with `npm test -- tests/sql-scaling.test.ts`. A controlled local
|
|
45
|
+
change from `CREATE TABLE` to `CREATE VIEW` in `createTableFromFile` must make
|
|
46
|
+
it fail as source rows read per query increase with the larger tree; restore
|
|
47
|
+
the implementation after the probe. The companion relation tests check that
|
|
48
|
+
queries survive source-file removal and enumerate file-reading views.
|
|
49
|
+
|
|
50
|
+
A compile retains parsed frontmatter, body, raw source and body coordinates in
|
|
51
|
+
its corpus. SQL preparation, document passes, folder pins, event anchors,
|
|
52
|
+
culture inheritance and prose-presence checks consume that shared result.
|
|
53
|
+
The compile guard counts actual Markdown reads and YAML parses for every file
|
|
54
|
+
in its fixture, including documentation and folder notes, and requires one of
|
|
55
|
+
each. Diagnostic positions consume retained source text when supplied.
|
|
56
|
+
|
|
57
|
+
Standing checks locate only findings they emit. YAML path lookups retain the
|
|
58
|
+
most recently located text's document and line counter; another text replaces
|
|
59
|
+
that single cache entry, so an edited note cannot inherit stale coordinates.
|
|
60
|
+
SQL preparation caches authored answers and stub-inclusive comparisons in
|
|
61
|
+
separate fields per query. Generated event fences read `entries` and `events`
|
|
62
|
+
and skip the comparison; their authored/generated boundary is recorded when
|
|
63
|
+
the sections are appended, independently of query text.
|
package/docs/diagnostics.md
CHANGED
|
@@ -170,7 +170,7 @@ package-build.config.yaml:382:64: error: package-build config: `site.sections.be
|
|
|
170
170
|
|
|
171
171
|
## A worked case: the three states of a note
|
|
172
172
|
|
|
173
|
-
A note with an empty body is a **stub**, and the diagnostics about one show each
|
|
173
|
+
A place note with an empty body is a **stub**, and the diagnostics about one show each
|
|
174
174
|
rule above in turn.
|
|
175
175
|
|
|
176
176
|
An empty body must be deliberate, so a stub that says nothing about itself is an
|
package/docs/guides/e2e.md
CHANGED
|
@@ -128,6 +128,33 @@ for interactive testing. Arguments after `--` are passed to the suite, for
|
|
|
128
128
|
example `package-build e2e run -- --browser chrome`. A port answering is not
|
|
129
129
|
enough: the harness waits until Foundry's join page shows the world is active.
|
|
130
130
|
|
|
131
|
+
## Choose a browser
|
|
132
|
+
|
|
133
|
+
For a Cypress suite, `e2e fast`, `e2e run` and `e2e open` use pinned
|
|
134
|
+
Chrome for Testing **155.0.8059.84** on macOS arm64 and Linux x64. The first run
|
|
135
|
+
downloads it; later runs reuse the cached executable. Each run prints the
|
|
136
|
+
resolved browser and version, and Cypress reports the browser in its header.
|
|
137
|
+
Other suite commands run as declared.
|
|
138
|
+
|
|
139
|
+
An explicit `--browser` in the configured suite or its extra arguments wins,
|
|
140
|
+
including `--browser=electron`. For example:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
package-build e2e fast -- --browser electron
|
|
144
|
+
package-build e2e run -- --browser /path/to/chrome
|
|
145
|
+
package-build e2e open -- --browser=chrome
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
A platform without a configured build requires an explicit installed browser.
|
|
149
|
+
The automatic download needs network access on first use. The cache location is,
|
|
150
|
+
in order: `HL_BROWSER_CACHE`, `browser-cache` beside `FOUNDRYVTT_CACHE`,
|
|
151
|
+
`HL_E2E_ROOT/browser-cache`, or `heroiclands/chrome-for-testing` under the user's
|
|
152
|
+
cache directory (`XDG_CACHE_HOME`, macOS `~/Library/Caches`, otherwise
|
|
153
|
+
`~/.cache`). CI keeps it inside the job's persistent `HL_E2E_ROOT`; point
|
|
154
|
+
`FOUNDRYVTT_CACHE` there too, or set `HL_BROWSER_CACHE` explicitly. Reseeding
|
|
155
|
+
and container teardown leave the browser cache intact. Renovate tracks the
|
|
156
|
+
exact Chrome pin in `e2e.mjs` through the repository's custom datasource.
|
|
157
|
+
|
|
131
158
|
## Iterate without reseeding
|
|
132
159
|
|
|
133
160
|
`fast` rebuilds declared targets, redeploys the full stage, cycles the world,
|
|
@@ -196,4 +223,13 @@ container started with the variable set joins the network but keeps the
|
|
|
196
223
|
environment it was created with; `--recreate` applies `FOUNDRY_AWS_CONFIG`.
|
|
197
224
|
`package-build container <stage> rm` with the variable set removes the server
|
|
198
225
|
and the network along with the container. The server is otherwise left running
|
|
199
|
-
between runs, bucket intact.
|
|
226
|
+
between runs, bucket intact. New and reused servers must answer the S3 HTTP
|
|
227
|
+
health check before Foundry starts; a ready filer alone is insufficient.
|
|
228
|
+
|
|
229
|
+
Both configuration paths must be readable regular files. When changing
|
|
230
|
+
worktrees, an existing server must bind the identities file from the current
|
|
231
|
+
checkout (symlinks to the same file are accepted). An incompatible or
|
|
232
|
+
uninspectable bind stops the start and names the server and expected path.
|
|
233
|
+
Restore the original checkout to keep its bucket data, or remove only the named
|
|
234
|
+
disposable S3 server with `docker rm -f <container>-s3` and rerun. Removing that
|
|
235
|
+
server discards its bucket data; the tool never removes it automatically.
|
package/docs/guides/packs.md
CHANGED
|
@@ -20,7 +20,8 @@ Start with one pack for each document class the notes produce. An Item, Actor,
|
|
|
20
20
|
Macro, Scene, or Adventure note can also produce a JournalEntry for its prose,
|
|
21
21
|
so a package with those notes generally needs a JournalEntry pack. A missing
|
|
22
22
|
pack for a document a note actually produces is a finding on that note. An
|
|
23
|
-
empty body
|
|
23
|
+
empty body without automatic Dictionary or Glossary content produces no prose
|
|
24
|
+
journal and needs no pack for it.
|
|
24
25
|
|
|
25
26
|
```yaml
|
|
26
27
|
packs:
|