@heroiclands/package-build 22.15.1 → 22.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. package/CHANGELOG.md +110 -0
  2. package/README.md +39 -678
  3. package/bin/{content-build.mjs → content-commands.mjs} +197 -118
  4. package/bin/package-build.mjs +315 -42
  5. package/bin/report.mjs +1 -1
  6. package/ci/ci-docker.mjs +6 -3
  7. package/ci/ci-steps.mjs +6 -4
  8. package/ci/content-format-reference.mjs +106 -0
  9. package/config.mjs +22 -2
  10. package/content-config.mjs +74 -134
  11. package/docs/api.md +296 -236
  12. package/docs/authoring/assets.md +31 -0
  13. package/docs/authoring/dates-and-calendars.md +85 -0
  14. package/docs/authoring/first-note.md +48 -0
  15. package/docs/authoring/frontmatter.md +40 -0
  16. package/docs/authoring/links-and-markup.md +137 -0
  17. package/docs/commands.md +633 -162
  18. package/docs/configuration.md +176 -140
  19. package/docs/content-format.md +50 -4229
  20. package/docs/design.md +32 -0
  21. package/docs/diagnostics.md +29 -22
  22. package/docs/getting-started.md +21 -877
  23. package/docs/guides/book.md +153 -0
  24. package/docs/guides/e2e.md +143 -0
  25. package/docs/guides/icons.md +126 -0
  26. package/docs/guides/localization.md +120 -0
  27. package/docs/guides/module-project.md +915 -0
  28. package/docs/guides/packs.md +167 -0
  29. package/docs/guides/reference-pages.md +148 -0
  30. package/docs/guides/release-and-deploy.md +114 -0
  31. package/docs/guides/site.md +152 -0
  32. package/docs/guides/system-project.md +45 -0
  33. package/docs/index.md +16 -0
  34. package/docs/project-setup.md +54 -35
  35. package/docs/reference/format-details.md +4362 -0
  36. package/docs/reference/note-types.md +532 -0
  37. package/engine/address-render.mjs +26 -0
  38. package/engine/address.mjs +3 -20
  39. package/engine/anchors.mjs +15 -6
  40. package/engine/asset-bindings.mjs +6 -2
  41. package/engine/base-compiler.mjs +47 -11
  42. package/engine/being-measurements.mjs +70 -0
  43. package/engine/calendar-artifacts.mjs +1 -1
  44. package/engine/calendar-choice.mjs +32 -0
  45. package/engine/calendar-format.mjs +441 -0
  46. package/engine/calendar-human.mjs +133 -0
  47. package/engine/calendar-notes.mjs +307 -88
  48. package/engine/calendars.mjs +8 -1
  49. package/engine/changelog-lint.mjs +2 -2
  50. package/engine/code-fences.mjs +23 -97
  51. package/engine/compile-corpus.mjs +6 -7
  52. package/engine/content-admonitions.mjs +114 -0
  53. package/engine/content-captions.mjs +181 -0
  54. package/engine/content-embeds.mjs +2 -2
  55. package/engine/content-footnotes.mjs +34 -0
  56. package/engine/content-format-check.mjs +2 -2
  57. package/engine/content-format.mjs +127 -73
  58. package/engine/content-format.yaml +746 -0
  59. package/engine/content-html.mjs +1 -1
  60. package/engine/content-icons.mjs +45 -92
  61. package/engine/content-images.mjs +22 -74
  62. package/engine/content-index.mjs +12 -3
  63. package/engine/content-links.mjs +21 -26
  64. package/engine/content-lint.mjs +1 -5
  65. package/engine/content-secrets.mjs +3 -1
  66. package/engine/content-tables.mjs +47 -1257
  67. package/engine/culture-choice.mjs +32 -0
  68. package/engine/date-conversion.mjs +47 -0
  69. package/engine/declaration-check.mjs +87 -0
  70. package/engine/docs-checks.mjs +140 -0
  71. package/engine/documentation-links.mjs +31 -0
  72. package/engine/exported-scene.mjs +1 -1
  73. package/engine/extension-attributes.mjs +74 -0
  74. package/engine/field-reference.mjs +1 -1
  75. package/engine/field-spec.mjs +4 -0
  76. package/engine/foreign-catalog.mjs +5 -5
  77. package/engine/format-generated.mjs +15 -0
  78. package/engine/foundry-entries.mjs +3 -1
  79. package/engine/frontmatter-lint.mjs +5 -1
  80. package/engine/frontmatter.mjs +10 -0
  81. package/engine/generate.mjs +2 -2
  82. package/engine/helpers.mjs +71 -117
  83. package/engine/homepage.mjs +2 -3
  84. package/engine/index-records.mjs +1 -0
  85. package/engine/index.mjs +18 -3
  86. package/engine/infobox-registry.mjs +3 -1
  87. package/engine/infobox.mjs +38 -20
  88. package/engine/item-compiler.mjs +10 -8
  89. package/engine/item-docs.mjs +7 -6
  90. package/engine/journals.mjs +51 -10
  91. package/engine/macros.mjs +1 -1
  92. package/engine/map-build.mjs +1 -1
  93. package/engine/map-dot.mjs +1 -1
  94. package/engine/markdown-expressions.mjs +118 -0
  95. package/engine/metadata-index.mjs +7 -3
  96. package/engine/note-addresses.mjs +1 -0
  97. package/engine/note-dates.mjs +314 -64
  98. package/engine/note-package.mjs +5 -25
  99. package/engine/note-state.mjs +6 -2
  100. package/engine/note-vocabulary.mjs +74 -19
  101. package/engine/number-words.mjs +75 -0
  102. package/engine/office-holders.mjs +188 -0
  103. package/engine/pack-config.mjs +2 -15
  104. package/engine/pack-router.mjs +24 -5
  105. package/engine/packages.mjs +3 -2
  106. package/engine/pathnames.mjs +21 -24
  107. package/engine/pdf-build.mjs +217 -55
  108. package/engine/pdf-fonts.mjs +2 -2
  109. package/engine/pdf-images.mjs +82 -0
  110. package/engine/pdf-render.mjs +174 -22
  111. package/engine/populations.mjs +3 -2
  112. package/engine/project-init.mjs +499 -0
  113. package/engine/prose-config.mjs +1 -1
  114. package/engine/prose-lint.mjs +7 -6
  115. package/engine/readability-lint.mjs +86 -0
  116. package/engine/reckoning-markers.mjs +176 -166
  117. package/engine/scenes.mjs +5 -2
  118. package/engine/schema-check.mjs +3 -3
  119. package/engine/site-build.mjs +87 -37
  120. package/engine/site-config.mjs +8 -8
  121. package/engine/site-index.mjs +4 -0
  122. package/engine/site-maps.mjs +1 -1
  123. package/engine/site-preview.mjs +19 -8
  124. package/engine/social-ties.mjs +5 -1
  125. package/engine/sql-tables.mjs +92 -22
  126. package/engine/web-wikilinks.mjs +15 -31
  127. package/engine/wikilink-syntax.mjs +4 -1
  128. package/engine/wikilinks.mjs +12 -14
  129. package/hm3/item-fields.mjs +1 -1
  130. package/hm3/items.mjs +12 -45
  131. package/index.mjs +2 -14
  132. package/manifest.mjs +31 -4
  133. package/markdownlint-config.mjs +1 -1
  134. package/package.json +32 -11
  135. package/prettier-config.mjs +1 -1
  136. package/sohl/being-info.mjs +3 -145
  137. package/sohl/index.mjs +1 -1
  138. package/sohl/infobox.mjs +2 -1
  139. package/sohl/item-builders.mjs +3 -27
  140. package/sohl/item-fields.mjs +61 -22
  141. package/sohl/kb-passes.mjs +2 -2
  142. package/sohl/note-schemas.mjs +0 -8
  143. package/stage.mjs +19 -0
  144. package/types/config.d.mts +12 -3
  145. package/types/content-config.d.mts +15 -81
  146. package/types/engine/address-render.d.mts +13 -0
  147. package/types/engine/address.d.mts +2 -11
  148. package/types/engine/anchors.d.mts +3 -4
  149. package/types/engine/asset-bindings.d.mts +9 -2
  150. package/types/engine/base-compiler.d.mts +1 -2
  151. package/types/engine/being-measurements.d.mts +16 -0
  152. package/types/engine/calendar-choice.d.mts +14 -0
  153. package/types/engine/calendar-format.d.mts +33 -0
  154. package/types/engine/calendar-human.d.mts +4 -0
  155. package/types/engine/calendar-notes.d.mts +5 -3
  156. package/types/engine/calendars.d.mts +5 -3
  157. package/types/engine/code-fences.d.mts +6 -72
  158. package/types/engine/compile-corpus.d.mts +1 -3
  159. package/types/engine/content-admonitions.d.mts +24 -0
  160. package/types/engine/content-captions.d.mts +45 -0
  161. package/types/engine/content-footnotes.d.mts +10 -0
  162. package/types/engine/content-format-check.d.mts +17 -4
  163. package/types/engine/content-format.d.mts +24 -11
  164. package/types/engine/content-icons.d.mts +14 -23
  165. package/types/engine/content-images.d.mts +2 -2
  166. package/types/engine/content-index.d.mts +9 -2
  167. package/types/engine/content-links.d.mts +3 -5
  168. package/types/engine/content-tables.d.mts +11 -140
  169. package/types/engine/culture-choice.d.mts +14 -0
  170. package/types/engine/date-conversion.d.mts +4 -0
  171. package/types/engine/declaration-check.d.mts +24 -0
  172. package/types/engine/docs-checks.d.mts +28 -0
  173. package/types/engine/documentation-links.d.mts +7 -0
  174. package/types/engine/exported-scene.d.mts +6 -2
  175. package/types/engine/extension-attributes.d.mts +14 -0
  176. package/types/engine/field-spec.d.mts +9 -0
  177. package/types/engine/format-generated.d.mts +7 -0
  178. package/types/engine/frontmatter.d.mts +14 -4
  179. package/types/engine/generate.d.mts +1 -1
  180. package/types/engine/helpers.d.mts +37 -92
  181. package/types/engine/homepage.d.mts +2 -3
  182. package/types/engine/index.d.mts +5 -0
  183. package/types/engine/infobox-registry.d.mts +3 -1
  184. package/types/engine/infobox.d.mts +17 -6
  185. package/types/engine/item-compiler.d.mts +4 -4
  186. package/types/engine/item-docs.d.mts +4 -3
  187. package/types/engine/journals.d.mts +10 -7
  188. package/types/engine/map-graphviz.d.mts +1 -1
  189. package/types/engine/markdown-expressions.d.mts +17 -0
  190. package/types/engine/note-dates.d.mts +47 -1
  191. package/types/engine/note-package.d.mts +3 -19
  192. package/types/engine/note-state.d.mts +2 -1
  193. package/types/engine/note-vocabulary.d.mts +9 -0
  194. package/types/engine/number-words.d.mts +4 -0
  195. package/types/engine/office-holders.d.mts +14 -0
  196. package/types/engine/pack-config.d.mts +1 -1
  197. package/types/engine/packages.d.mts +3 -2
  198. package/types/engine/pdf-images.d.mts +38 -0
  199. package/types/engine/populations.d.mts +2 -2
  200. package/types/engine/project-init.d.mts +17 -0
  201. package/types/engine/prose-config.d.mts +1 -1
  202. package/types/engine/prose-lint.d.mts +3 -2
  203. package/types/engine/readability-lint.d.mts +22 -0
  204. package/types/engine/reckoning-markers.d.mts +13 -26
  205. package/types/engine/schema-check.d.mts +3 -3
  206. package/types/engine/site-build.d.mts +38 -28
  207. package/types/engine/site-config.d.mts +2 -2
  208. package/types/engine/site-index.d.mts +4 -0
  209. package/types/engine/site-preview.d.mts +1 -1
  210. package/types/engine/social-ties.d.mts +8 -2
  211. package/types/engine/sql-tables.d.mts +13 -2
  212. package/types/engine/web-wikilinks.d.mts +2 -1
  213. package/types/engine/wikilinks.d.mts +7 -1
  214. package/types/hm3/items.d.mts +5 -6
  215. package/types/labels.d.mts +40 -0
  216. package/types/manifest.d.mts +3 -3
  217. package/types/sohl/actors.d.mts +2 -2
  218. package/types/sohl/being-info.d.mts +3 -43
  219. package/types/sohl/index.d.mts +1 -1
  220. package/types/sohl/infobox.d.mts +5 -2
  221. package/types/sohl/item-fields.d.mts +4 -13
  222. package/types/stage.d.mts +9 -0
  223. package/CONTENT.md +0 -3239
@@ -0,0 +1,167 @@
1
+ ---
2
+ shortcode: guidespacks
3
+ name: { full: "Compendium packs" }
4
+ type: doc
5
+ subType: howto
6
+ ---
7
+
8
+ # Compendium packs
9
+
10
+ A Foundry content package declares its compendiums in `packs:` in
11
+ `package-build.config.yaml`. Each entry names a pack and the Foundry document
12
+ class it holds. The build uses the same list for the manifest and for its
13
+ compilation passes. The [configuration reference](../configuration.md) defines
14
+ every pack key; this guide covers how to choose and route packs as a package
15
+ grows.
16
+
17
+ ## Choose the pack layout
18
+
19
+ Start with one pack for each document class the notes produce. An Item, Actor,
20
+ Macro, Scene, or Adventure note can also produce a JournalEntry for its prose,
21
+ so a package with those notes generally needs a JournalEntry pack. A missing
22
+ pack for a document a note actually produces is a finding on that note. An
23
+ empty body produces no prose journal and needs no pack for it.
24
+
25
+ ```yaml
26
+ packs:
27
+ - { name: items, type: Item, label: Items }
28
+ - { name: actors, type: Actor, label: Actors }
29
+ - { name: journals, type: JournalEntry, label: Journals }
30
+ ```
31
+
32
+ Item and Actor packs for a system also need the system selection and version
33
+ declarations described in [configuration](../configuration.md). A documentation
34
+ package has no Foundry packs or manifest; the
35
+ [getting started guide](../getting-started.md) shows that package kind.
36
+
37
+ A pack name forms part of a compendium UUID. Choose it as a stable identifier;
38
+ the label can change independently. Pack order in the configuration is the
39
+ order shown in the generated manifest. The compiler arranges its passes so a
40
+ pass that reads another pack's output runs after every pack of that document
41
+ class. In particular, Actor compilation follows the Item packs it reads.
42
+
43
+ ## Route notes between packs of one class
44
+
45
+ Multiple packs may hold one document class. A single pack of a class is its
46
+ implicit default. With several, mark one `default: true` or give each relevant
47
+ note an explicit `data.pack`:
48
+
49
+ ```yaml
50
+ packs:
51
+ - { name: general, type: JournalEntry, default: true }
52
+ - { name: mysteries, type: JournalEntry }
53
+ ```
54
+
55
+ ```yaml
56
+ shortcode: secondsight
57
+ name: { full: Second Sight }
58
+ type: doc
59
+ subType: concept
60
+ data: { pack: mysteries }
61
+ ```
62
+
63
+ The note's pack declaration routes its own document. A derived prose journal
64
+ uses the default JournalEntry pack, so an Item note's `data.pack` routes its
65
+ Item and does not also route its prose. An unknown pack, a pack of another
66
+ document class, or a companion pack is an error. If a class has several packs
67
+ and no default, an unassigned note of that class is an error too.
68
+
69
+ For a page that belongs on the site and in the content index but in no
70
+ compendium, a journal-only note can declare `data: {pack: none}`. An Item,
71
+ Actor, Macro, Scene, or Adventure note cannot use that value because it would
72
+ drop the document the note creates. The
73
+ [content format](../reference/format-details.md#the-pack-a-note-compiles-into) defines
74
+ this field and its placement.
75
+
76
+ ## Build for more than one system
77
+
78
+ A pack can declare `system`, and the router chooses a default separately for
79
+ each document class and system. One Item pack for each system therefore needs
80
+ no `default: true` flag. A note with both system blocks produces a document
81
+ for each block, shaped by that system's item builder and stamped with that
82
+ system's version. A note with only one block produces only that system's
83
+ document.
84
+
85
+ ```yaml
86
+ itemBuilders: [sohl, hm3]
87
+ systems:
88
+ sohl: { compatibility: { verified: "0.9.0" } }
89
+ hm3: { compatibility: { verified: "1.6.3" } }
90
+ packs:
91
+ - { name: items-sohl, type: Item, system: sohl }
92
+ - { name: items-hm3, type: Item, system: hm3 }
93
+ - { name: actors-sohl, type: Actor, system: sohl }
94
+ - { name: actors-hm3, type: Actor, system: hm3 }
95
+ - { name: journals, type: JournalEntry }
96
+ ```
97
+
98
+ A system block's `pack` selects that system's document pack. A block naming a
99
+ pack for another system is an error. A shared `data.pack` that names a pack
100
+ for one system does not route the other system into it; that system uses its
101
+ own default. A pack with no `system` may serve as a default for either.
102
+
103
+ The `itemBuilders` registry supplies the accepted item types and the builder
104
+ for each type. The named `sohl` and `hm3` registries ship with the package.
105
+ When both define a type, the build selects the builder for the pack's system.
106
+ The [configuration reference](../configuration.md) covers the version and
107
+ registry declarations.
108
+
109
+ ## Supply a custom item builder
110
+
111
+ A package whose item builders are code uses `package-build.config.mjs` and
112
+ passes the builder table to `defineConfig`. Import `defineConfig` from the
113
+ `content-config` entry point so the configuration module loads independently
114
+ of the compilers:
115
+
116
+ ```js
117
+ import { defineConfig } from "@heroiclands/package-build/content-config";
118
+ import { ITEM_BUILDERS } from "./build/item-builders.mjs";
119
+
120
+ export default defineConfig({
121
+ rootDir: import.meta.dirname,
122
+ contentPackage: "example",
123
+ foundryPackage: "example-module",
124
+ packageKind: "modules",
125
+ compatibility: { minimum: "14.359", verified: "14.364" },
126
+ stats: { lastModifiedBy: "examplebuilder000" },
127
+ itemBuilders: ITEM_BUILDERS,
128
+ packs: [{ name: "items", type: "Item" }],
129
+ });
130
+ ```
131
+
132
+ This form supplies values that a YAML configuration derives from its location
133
+ and adjacent `package.json`. Declare one configuration file in the project:
134
+ the loader refuses a directory containing both YAML and MJS configurations.
135
+ The [API reference](../api.md) describes `defineConfig` and the builder
136
+ contract.
137
+
138
+ ## Use prebuilt and companion packs
139
+
140
+ `prebuilt` points to per-document JSON that the package maintains as input.
141
+ The build compiles that JSON into LevelDB without running a note-generation
142
+ pass for the pack. A prebuilt pack cannot have a default or companions, and
143
+ cannot itself be a companion.
144
+
145
+ A companion is emitted by its parent's pass. For example, a Scene pass can
146
+ also write an Adventure pack that groups its scenes. Declare the companion
147
+ under the parent; no note routes directly into it:
148
+
149
+ ```yaml
150
+ packs:
151
+ - name: scenes
152
+ type: Scene
153
+ companions:
154
+ - { name: adventures, type: Adventure }
155
+ ```
156
+
157
+ The [pack configuration reference](../configuration.md) lists the remaining
158
+ constraints and fields.
159
+
160
+ ## Compile and inspect
161
+
162
+ Run `package-build package compile` to compile every configured pack. Run it
163
+ with a pack name to compile one pack; if that pass reads another pack's output,
164
+ the needed output must already exist. The full compile orders those passes for
165
+ you. `package-build package unpack` reads a built pack back into JSON for
166
+ inspection. See the [command reference](../commands.md) for their arguments
167
+ and output paths.
@@ -0,0 +1,148 @@
1
+ ---
2
+ shortcode: guidesreferencepages
3
+ name: { full: "Reference pages and content indexes" }
4
+ type: doc
5
+ subType: howto
6
+ ---
7
+
8
+ # Reference pages and content indexes
9
+
10
+ A reference page gives readers an entry point into a group of notes. Author it
11
+ as a normal content note, so it has a stable Address, can link to its subjects,
12
+ and can be selected for the site or book. The JSON Lines content index serves a
13
+ different reader: build passes and tools use it to find notes, assets, names,
14
+ relationships, and generated document destinations.
15
+
16
+ The [content format](../content-format.md) defines note types, Address fields,
17
+ and links. The [command reference](../commands.md) gives the index and generated
18
+ page commands; [configuration](../configuration.md) defines their paths.
19
+
20
+ ## Author an entry page
21
+
22
+ Use `type: doc` and `subType: reference` for an out-of-world lookup page. A
23
+ page introducing a content type conventionally uses that type as its
24
+ shortcode. Its body supplies the explanation, links, and any SQL tables a
25
+ reader needs:
26
+
27
+ ````markdown
28
+ ---
29
+ shortcode: affiliation
30
+ name: { full: Affiliations }
31
+ type: doc
32
+ subType: reference
33
+ data: { pack: none }
34
+ ---
35
+
36
+ # Affiliations
37
+
38
+ Affiliations describe the groups a person belongs to and the offices they may
39
+ hold. Start with [[affiliation-watch|The Watch]] for a local example.
40
+
41
+ ```sql
42
+ SELECT address.slug AS _ref, name.full AS "Name"
43
+ FROM notes
44
+ WHERE type = 'affiliation'
45
+ ```
46
+ ````
47
+
48
+ `data.pack: none` is appropriate when the page belongs on the site and in the
49
+ index but does not need a Foundry compendium entry. A documentation package
50
+ has no packs at all. A page with an empty body is a stub: it remains in the
51
+ index for data references, but publishes no page address or anchors. Write a
52
+ description for a stub and leave off the `draft` tag; use `draft` for a page
53
+ with prose still in progress. The [stub rules](../reference/format-details.md#a-stub-is-a-note-with-an-empty-body)
54
+ and [pack routing](packs.md) cover these cases.
55
+
56
+ ## Link to the intended target
57
+
58
+ An Address identifies a package, system, type, and shortcode. In a normal
59
+ `[[link|label]]`, an omitted package means the current package and an omitted
60
+ system means `note`, the readable content. For example,
61
+ `[[affiliation-watch|The Watch]]` names the local readable note. An explicit
62
+ game system names an Actor or Item, and `none` names a systemless asset,
63
+ Scene, Macro, or Folder. A link to another package states all four segments:
64
+ `[[thalorna-note-affiliation-watch|The Watch]]`.
65
+
66
+ An image embed `![[image-watchcrest|Watch crest]]` defaults to system `none`.
67
+ Frontmatter Address fields take the defaults declared for their position; an
68
+ image field defaults to `none`, while most shared `data:` references default
69
+ to `note`. Use a complete Address in generated content and SQL comparisons:
70
+ `thalorna-note-affiliation-watch`, rather than its bare `watch` shortcode.
71
+ The [Address reference](../reference/format-details.md#addresses) lists the accepted
72
+ short forms and defaults.
73
+
74
+ ## Generate a field reference from item builders
75
+
76
+ A package with Item builders can generate its Item frontmatter page from the
77
+ builder field declarations. Set `docs.itemFields` to give the page its title,
78
+ destination, and introductory prose:
79
+
80
+ ```yaml
81
+ docs:
82
+ itemFields:
83
+ title: Item Fields
84
+ out: assets/content/Reference/Item_Fields.md
85
+ preamble:
86
+ - These tables list the fields accepted by the configured Item builders.
87
+ ```
88
+
89
+ ```bash
90
+ package-build docs item-fields
91
+ package-build docs item-fields --check
92
+ ```
93
+
94
+ When the output is under `paths.content`, the generator writes a complete
95
+ `doc/reference` note with a shortcode derived from the output filename, a
96
+ title in `name.full`, and `data.pack: none`. `docs.itemFields.frontmatter` can
97
+ add or override its envelope. Outside the content tree, the output is a
98
+ standalone Markdown page without note frontmatter. `--check` compares the
99
+ whole generated file with the committed copy and exits unsuccessfully when
100
+ they differ. A documentation package cannot declare Item builders or this
101
+ reference generator.
102
+
103
+ ## Use the content index
104
+
105
+ Run the index command in a content package to produce
106
+ `build/content-index/<contentPackage>-metadata.jsonl`, or use the configured
107
+ `paths.contentIndex` directory:
108
+
109
+ ```bash
110
+ package-build content-index
111
+ jq -r 'select(.type == "affiliation") | .name.full' \
112
+ build/content-index/thalorna-metadata.jsonl
113
+ ```
114
+
115
+ Each note record carries its authored frontmatter together with derived
116
+ `package`, `file`, `address`, `anchors`, and document destinations. It also has
117
+ ASCII-folded `nameAscii` and `aliasesAscii` for searching names typed without
118
+ diacritics. Asset files under `assets/icons`, `assets/images`, and
119
+ `assets/audio` have records in the same index, identified by an `asset` block.
120
+ The index is disposable build output; regenerate it from the authored tree
121
+ when the content changes.
122
+
123
+ The record's `address.canonical` is the full Address. Its `address.slug` is a
124
+ local web link target. A stub has `address: null` and `anchors: null`; its
125
+ frontmatter remains queryable. An Item or Actor note can have both a readable
126
+ `note` record and a game-system document destination. A generated
127
+ `documentation` pointer connects a system document to its readable note.
128
+ Consumers can use the index's own addresses and file paths rather than
129
+ reconstructing them from filenames.
130
+
131
+ ## Resolve another package
132
+
133
+ In a Foundry package, declare a content-bearing dependency under
134
+ `relationships`, then fetch its published index before a build that links into
135
+ it:
136
+
137
+ ```bash
138
+ package-build deps fetch
139
+ ```
140
+
141
+ The fetch stores the versioned metadata in `paths.metadataCache`. A local
142
+ dependency build can be read with `package-build deps fetch --from <path>`.
143
+ The dependency's published manifest advertises its metadata URL. A build
144
+ reports a missing index instead of downloading it while rendering. A
145
+ relationship with `contentIndex: false` is for a Foundry dependency whose
146
+ content is not addressable from this package. See the
147
+ [dependency configuration](../configuration.md#relationships) for the
148
+ declaration and cache rules.
@@ -0,0 +1,114 @@
1
+ ---
2
+ shortcode: guidesreleaseanddeploy
3
+ name: { full: "Release and deploy a package" }
4
+ type: doc
5
+ subType: howto
6
+ ---
7
+
8
+ # Release and deploy a package
9
+
10
+ A Foundry package has two delivery paths. `package-build release` prepares
11
+ files for a GitHub release that Foundry can install. `package-build deploy`
12
+ places the staged build directly in one Foundry data directory for testing or
13
+ operation. Both start with the package built from its source and configuration.
14
+ The [command reference](../commands.md) gives each command's options; the
15
+ [configuration reference](../configuration.md) defines the stage and manifest.
16
+
17
+ ## Check published addresses before a release
18
+
19
+ An Item address is an interface other packages can resolve against. Compare a
20
+ candidate build with an explicit released artifact when changing note
21
+ shortcodes or withdrawing Items:
22
+
23
+ ```bash
24
+ package-build addresses diff --from build/baseline/module.zip
25
+ package-build addresses diff --from build/baseline/module.zip --strict
26
+ ```
27
+
28
+ The baseline can be a release ZIP or an unpacked build directory; the command
29
+ does not download one. It reports an address as **renamed** when the same
30
+ document ID appears under another address, and **withdrawn** when that ID
31
+ appears under none. Findings are warnings by default. `--strict` turns them
32
+ into errors for a release gate. The comparison reads shipped Item packs, so it
33
+ reports the surface consumers actually resolve rather than inferring changes
34
+ from filenames. Use the [Address reference](../reference/format-details.md#addresses)
35
+ when choosing a durable shortcode.
36
+
37
+ ## Build the release files
38
+
39
+ Build the repository's staged package and content index, then run:
40
+
41
+ ```bash
42
+ package-build release
43
+ ```
44
+
45
+ The command writes a Foundry ZIP and its `system.json` or `module.json`
46
+ manifest under `build/dist/`. The ZIP contains the staged tree at its root,
47
+ which is the shape Foundry installs. When the manifest advertises a content
48
+ index, the corresponding metadata JSONL is also placed beside the ZIP. A
49
+ manifest that advertises an index the build has not produced fails the
50
+ release. An opted-in staged `schema.json` is published beside it too.
51
+
52
+ When the package publishes content and has a book configuration, the release
53
+ also builds a PDF beside the archive. Book findings are reported without
54
+ discarding the installable archive. `package-build release --no-pdf` skips the
55
+ book step. The [book guide](book.md) covers selecting and checking its pages.
56
+
57
+ The repository's build scripts decide how the staged tree is assembled. A
58
+ typical content build runs `package-build content-index`,
59
+ `package-build assets`, `package-build package compile`, and
60
+ `package-build manifest` before release. Run `package-build bundle check` when
61
+ the package ships a JavaScript bundle; it checks that the staged manifest
62
+ loads that bundle once and in the right module form.
63
+
64
+ ## Deploy a staged build to Foundry
65
+
66
+ Create `.env.local` at the repository root for machine-specific stage paths
67
+ and credentials. Keep it ignored by git:
68
+
69
+ ```dotenv
70
+ FOUNDRYVTT_DEV_DATA=/path/to/foundry-data
71
+ FOUNDRYVTT_QA_DATA=yourhost:/srv/docker/data/foundryvtt-qa
72
+ FOUNDRYVTT_PROD_DATA=yourhost:/srv/docker/data/foundryvtt-prod
73
+ ```
74
+
75
+ The CLI loads `.env.local` before `.env`. A variable already in the shell takes
76
+ precedence over either file; `.env.local` takes precedence over `.env`. A
77
+ separate git worktree needs its own copy of this ignored file. Deploy the
78
+ build already under `packageBuild.stageDir`:
79
+
80
+ ```bash
81
+ package-build deploy dev
82
+ package-build container dev status
83
+ package-build container dev restart
84
+ ```
85
+
86
+ The data root can be an absolute local path or a `[user@]host:/absolute/path`
87
+ SFTP destination. The CLI appends `Data/systems/<id>` or `Data/modules/<id>`
88
+ for the package. Paths in `.env.local` are literal: `~` and shell variables
89
+ are not expanded. Keep stage paths pointed at distinct Foundry data roots.
90
+ The deploy command stages a complete copy beside the installed package and
91
+ swaps it into place, so it does not rewrite open LevelDB files one by one.
92
+ For a remote destination it uses the SSH agent unless the stage names an
93
+ explicit key. The `container` command manages the Foundry Docker instance for
94
+ the same stage;
95
+ `restart` stops it, clears a stale lock, then starts it. See the
96
+ [container command](../commands.md#package-build-container-stage-action) for
97
+ the other actions and environment variables.
98
+
99
+ ## Publish a package-build npm version
100
+
101
+ For this toolchain's own npm release, a pull request with a change installers
102
+ meet carries one changeset. An internal or documentation-only change carries
103
+ none. The shared repository rules choose the bump: a non-optional user-visible
104
+ change is minor; an optional command, flag, or key is patch. A major bump
105
+ requires the maintainer's direct decision. `package-build changelog check`
106
+ checks the quality of any pending changeset.
107
+
108
+ Merging a changeset to `main` makes the **Version Packages** pull request. Its
109
+ generated changelog section is reviewed as the release note. Merging that
110
+ pull request runs the **Publish to npm** workflow: npm Trusted Publishing
111
+ publishes the version, and the workflow creates its version tag and GitHub
112
+ Release. The workflow's manual dispatch can retry publishing a version already
113
+ merged to `main`. The [npm package page](https://www.npmjs.com/package/@heroiclands/package-build)
114
+ shows the published version and README.
@@ -0,0 +1,152 @@
1
+ ---
2
+ shortcode: guidessite
3
+ name: { full: "Build a content website" }
4
+ type: doc
5
+ subType: howto
6
+ ---
7
+
8
+ # Build a content website
9
+
10
+ `package-build site` turns the package's content notes into a Hugo source
11
+ tree. Hugo renders that tree with the shared theme. The build reads the same
12
+ note addresses used by content indexes and links, so a page's URL follows the
13
+ note it publishes.
14
+
15
+ The site has an authored homepage and one page for each other publishable note
16
+ in the content tree. The [configuration reference](../configuration.md)
17
+ defines the site settings; the [command reference](../commands.md) lists the
18
+ build actions and options.
19
+
20
+ ## Author the homepage
21
+
22
+ Every content package needs exactly one note with `type: homepage`. Its
23
+ `shortcode` makes it linkable from another note, while the site serves its
24
+ body at the package root:
25
+
26
+ ```markdown
27
+ ---
28
+ shortcode: root
29
+ name: { full: The Setting Guide }
30
+ type: homepage
31
+ ---
32
+
33
+ # The Setting Guide
34
+
35
+ Start with [Introduction](doc-introduction/).
36
+ ```
37
+
38
+ The homepage's body is published as Markdown. Write ordinary Markdown links
39
+ there, with addresses relative to the package root. Another note can refer to
40
+ it with `[[homepage-root|The Setting Guide]]`. The homepage creates no
41
+ Foundry compendium document and has no document ID. Its filename does not
42
+ decide its role; the frontmatter does.
43
+
44
+ The content tree controls the rest of the site. A tree containing only its
45
+ homepage publishes that page alone. Each additional publishable note becomes
46
+ its own page. The content index is a separate build artifact emitted by
47
+ `package-build content-index`.
48
+
49
+ Remove `publish.site` from package configurations. The presence of content
50
+ notes determines whether the site and book contain pages beyond the homepage.
51
+
52
+ ## Configure the site frame
53
+
54
+ A site with content pages declares its asset host and description. A
55
+ documentation package can give the site its own title; a
56
+ Foundry package can use its manifest title:
57
+
58
+ ```yaml
59
+ site:
60
+ title: The Setting Guide
61
+ assets: https://cdn.heroiclands.org
62
+ description: A guide to the setting and its people.
63
+ ```
64
+
65
+ The site title goes into Hugo's generated configuration. `site.description`
66
+ is plain text for the page's metadata. `site.assets` is an absolute HTTP or
67
+ HTTPS host for imagery. `package.json` supplies the homepage URL; it must
68
+ agree with the content package's address. The
69
+ [configuration reference](../configuration.md#site) covers the other site
70
+ keys, including `base`, `packages`, `notfound`, and `hugo`.
71
+
72
+ `site.hugo` can add Hugo options the build does not derive. Keys the build
73
+ owns, such as `baseURL`, `title`, and the generated menu, are refused there.
74
+ The menu comes from the navigation fetched by `package-build deps fetch`.
75
+ The site build reads that cached navigation and reports a missing cache.
76
+
77
+ ## Make entry pages and indexes
78
+
79
+ Each content note publishes one page at its Address-derived path. A `doc`
80
+ note can serve as a reader-facing index, with links and a SQL content table
81
+ over the notes it introduces:
82
+
83
+ ````markdown
84
+ ---
85
+ shortcode: beings
86
+ name: { full: Beings }
87
+ type: doc
88
+ subType: concept
89
+ data: { pack: none }
90
+ ---
91
+
92
+ # Beings
93
+
94
+ People and creatures of the setting.
95
+
96
+ ```sql
97
+ SELECT address.slug AS _ref, name.full AS "Name"
98
+ FROM notes
99
+ WHERE type = 'being'
100
+ ORDER BY name.full
101
+ ```
102
+ ````
103
+
104
+ Link that page from the homepage. `data.pack: none` keeps this journal-only
105
+ note out of Foundry compendiums while leaving its web page and content-index
106
+ record available. A SQL fence queries the content index; the
107
+ [content format](../content-format.md) defines its result columns and fence
108
+ options.
109
+
110
+ The build writes no automatic section, type, tag, or listing pages between
111
+ the homepage and the authored pages. Hugo's section, taxonomy, term, and RSS
112
+ kinds are disabled for these sites. A package's navigation above individual
113
+ notes is therefore a set of authored pages, each choosing its own contents.
114
+
115
+ ## Use links, relations, and maps
116
+
117
+ Wikilinks resolve through the address index. Each emitted page receives
118
+ derived `related` entries for its outgoing links and backlinks. Place pages
119
+ can receive `contains` and `held_by` entries from place parents and
120
+ affiliation domains; affiliation pages can receive `holdings`. These values
121
+ come from the content graph and should be read as generated page metadata.
122
+
123
+ Place relationships can also produce a map alongside the page. The page
124
+ links to that map as a local page resource; a place with no applicable
125
+ relationship has no map. Set `site.maps: false` to omit these drawings. The
126
+ [book guide](book.md) covers full-page maps in PDF, and the
127
+ [packs guide](packs.md) covers documents compiled for Foundry.
128
+
129
+ A package with a named `site.pass` can apply its own body transformation
130
+ before wikilinks resolve. The pass runs inside code-fence protection, so a
131
+ fenced example remains literal. `site.passOptions` supplies that named pass's
132
+ options. This is a package-specific extension point; keep the general note
133
+ format and link behavior in the [content format](../content-format.md).
134
+
135
+ ## Build and serve
136
+
137
+ ```bash
138
+ package-build deps fetch
139
+ package-build content-index
140
+ package-build site
141
+ hugo --source build/hugo
142
+ ```
143
+
144
+ `package-build site` writes `build/hugo/hugo.toml` and its content mount
145
+ under `build/hugo/content/`. Hugo writes rendered pages under `build/site/`.
146
+ `package-build site-root` adds the root headers and search index after Hugo
147
+ runs. The output under `build/` is disposable; a site build replaces its
148
+ content mount so a deleted note cannot leave a page behind.
149
+
150
+ A package created by `package-build init` includes `npm run build:site` for
151
+ this sequence and `npm run serve:site` for a local Hugo server. The site
152
+ requires Hugo Extended and the shared theme in the project's dependencies.
@@ -0,0 +1,45 @@
1
+ ---
2
+ shortcode: guidessystemproject
3
+ name: { full: "Building a Foundry system" }
4
+ type: doc
5
+ subType: howto
6
+ ---
7
+
8
+ # Building a Foundry system
9
+
10
+ A system repository owns its Foundry source and its content package. The system's JavaScript, templates, styles, and localization are repository source; Markdown notes under `assets/content/` describe setting material and compile into the configured packs, site, book, and content index. Both sides are assembled by the same `package-build.config.yaml`.
11
+
12
+ ## Initialize the project
13
+
14
+ ```bash
15
+ npm exec --package=@heroiclands/package-build -- package-build init my-system --kind systems --name my-system --title "My System" --description "A Foundry game system." --author "Your Name" --license original
16
+ cd my-system
17
+ npm install
18
+ npm run lint
19
+ ```
20
+
21
+ The initializer writes `package.json`, `package-build.config.yaml`, shared formatting configuration, a homepage and introduction note, `book.yaml`, localization, and npm scripts. It configures a JournalEntry pack, website, and book. It does not invent your Actor and Item DataModels or source bundle. Add those as the system grows, and declare every staged asset and pack in the build configuration. [Configuration](../configuration.md) gives the exact keys; [project setup](../project-setup.md) explains the scripts and generated directories.
22
+
23
+ `packageKind: systems` determines Foundry's package kind. `contentPackage` is the first segment of every content Address and must contain lowercase letters and digits. `package.json` supplies the package ID, version, and repository URL. The Foundry manifest is generated from these sources; keep no hand-edited second manifest.
24
+
25
+ ## Add source and content
26
+
27
+ Put system code under `src/`, templates under `templates/`, styles under `styles/`, and localization under `lang/`. Configure the build to stage the outputs Foundry loads and to validate the bundle against the generated manifest. [Project setup](../project-setup.md) describes the stage, language and bundle scripts; [localization](localization.md) covers keys and templates.
28
+
29
+ Put authored notes under `assets/content/` in any folder arrangement that helps the team. The note's frontmatter determines its content type and system document. Start with [one note](../authoring/first-note.md), then add [system blocks](../authoring/frontmatter.md) to a being or Item. The shared body makes one JournalEntry even if both SoHL and HM3 blocks appear; game-specific fields come from the respective block.
30
+
31
+ A system can own images, icons, and audio under their addressable roots. Keep provenance with each authored asset. [Assets](../authoring/assets.md) explains the roots and records. Set `packs` in the configuration for the compendiums the system ships; [packs](packs.md) explains routing and document compilation.
32
+
33
+ ## Build and review
34
+
35
+ ```bash
36
+ npm run build:db
37
+ npm run build:site
38
+ npm run serve:site
39
+ npm run build:book
40
+ npm run build:noci
41
+ ```
42
+
43
+ `build:db` writes the content index, stages assets, and compiles configured packs. `build:site` writes site content and renders it with Hugo Extended; `serve:site` starts a local Hugo preview. `build:book` uses Typst. `build:noci` runs lint, database, and manifest steps without reinstalling dependencies. Inspect `build/packs-json/` for compiled document data and `build/stage/` for what Foundry receives. Everything under `build/` is generated and can be deleted.
44
+
45
+ The [testing guide](e2e.md) covers a disposable Foundry world. The [release guide](release-and-deploy.md) covers packaging and deployment. Site deployment needs its own hosting configuration; local builds do not.
package/docs/index.md ADDED
@@ -0,0 +1,16 @@
1
+ ---
2
+ shortcode: root
3
+ name: { full: Package Build Documentation }
4
+ type: homepage
5
+ description: Guides and reference for building HeroicLands Foundry systems, modules, and content.
6
+ ---
7
+
8
+ # Package Build Documentation
9
+
10
+ Build a Foundry system or module, author its content once, and publish it to Foundry, the web, and a book.
11
+
12
+ - [Getting started](getting-started.md)
13
+ - [Authoring content](content-format.md)
14
+ - [Commands](commands.md)
15
+ - [Configuration](configuration.md)
16
+ - [API reference](api.md)