@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.
- package/CHANGELOG.md +110 -0
- package/README.md +39 -678
- package/bin/{content-build.mjs → content-commands.mjs} +197 -118
- package/bin/package-build.mjs +315 -42
- package/bin/report.mjs +1 -1
- package/ci/ci-docker.mjs +6 -3
- package/ci/ci-steps.mjs +6 -4
- package/ci/content-format-reference.mjs +106 -0
- package/config.mjs +22 -2
- package/content-config.mjs +74 -134
- package/docs/api.md +296 -236
- package/docs/authoring/assets.md +31 -0
- package/docs/authoring/dates-and-calendars.md +85 -0
- package/docs/authoring/first-note.md +48 -0
- package/docs/authoring/frontmatter.md +40 -0
- package/docs/authoring/links-and-markup.md +137 -0
- package/docs/commands.md +633 -162
- package/docs/configuration.md +176 -140
- package/docs/content-format.md +50 -4229
- package/docs/design.md +32 -0
- package/docs/diagnostics.md +29 -22
- package/docs/getting-started.md +21 -877
- package/docs/guides/book.md +153 -0
- package/docs/guides/e2e.md +143 -0
- package/docs/guides/icons.md +126 -0
- package/docs/guides/localization.md +120 -0
- package/docs/guides/module-project.md +915 -0
- package/docs/guides/packs.md +167 -0
- package/docs/guides/reference-pages.md +148 -0
- package/docs/guides/release-and-deploy.md +114 -0
- package/docs/guides/site.md +152 -0
- package/docs/guides/system-project.md +45 -0
- package/docs/index.md +16 -0
- package/docs/project-setup.md +54 -35
- package/docs/reference/format-details.md +4362 -0
- package/docs/reference/note-types.md +532 -0
- package/engine/address-render.mjs +26 -0
- package/engine/address.mjs +3 -20
- package/engine/anchors.mjs +15 -6
- package/engine/asset-bindings.mjs +6 -2
- package/engine/base-compiler.mjs +47 -11
- package/engine/being-measurements.mjs +70 -0
- package/engine/calendar-artifacts.mjs +1 -1
- package/engine/calendar-choice.mjs +32 -0
- package/engine/calendar-format.mjs +441 -0
- package/engine/calendar-human.mjs +133 -0
- package/engine/calendar-notes.mjs +307 -88
- package/engine/calendars.mjs +8 -1
- package/engine/changelog-lint.mjs +2 -2
- package/engine/code-fences.mjs +23 -97
- package/engine/compile-corpus.mjs +6 -7
- package/engine/content-admonitions.mjs +114 -0
- package/engine/content-captions.mjs +181 -0
- package/engine/content-embeds.mjs +2 -2
- package/engine/content-footnotes.mjs +34 -0
- package/engine/content-format-check.mjs +2 -2
- package/engine/content-format.mjs +127 -73
- package/engine/content-format.yaml +746 -0
- package/engine/content-html.mjs +1 -1
- package/engine/content-icons.mjs +45 -92
- package/engine/content-images.mjs +22 -74
- package/engine/content-index.mjs +12 -3
- package/engine/content-links.mjs +21 -26
- package/engine/content-lint.mjs +1 -5
- package/engine/content-secrets.mjs +3 -1
- package/engine/content-tables.mjs +47 -1257
- package/engine/culture-choice.mjs +32 -0
- package/engine/date-conversion.mjs +47 -0
- package/engine/declaration-check.mjs +87 -0
- package/engine/docs-checks.mjs +140 -0
- package/engine/documentation-links.mjs +31 -0
- package/engine/exported-scene.mjs +1 -1
- package/engine/extension-attributes.mjs +74 -0
- package/engine/field-reference.mjs +1 -1
- package/engine/field-spec.mjs +4 -0
- package/engine/foreign-catalog.mjs +5 -5
- package/engine/format-generated.mjs +15 -0
- package/engine/foundry-entries.mjs +3 -1
- package/engine/frontmatter-lint.mjs +5 -1
- package/engine/frontmatter.mjs +10 -0
- package/engine/generate.mjs +2 -2
- package/engine/helpers.mjs +71 -117
- package/engine/homepage.mjs +2 -3
- package/engine/index-records.mjs +1 -0
- package/engine/index.mjs +18 -3
- package/engine/infobox-registry.mjs +3 -1
- package/engine/infobox.mjs +38 -20
- package/engine/item-compiler.mjs +10 -8
- package/engine/item-docs.mjs +7 -6
- package/engine/journals.mjs +51 -10
- package/engine/macros.mjs +1 -1
- package/engine/map-build.mjs +1 -1
- package/engine/map-dot.mjs +1 -1
- package/engine/markdown-expressions.mjs +118 -0
- package/engine/metadata-index.mjs +7 -3
- package/engine/note-addresses.mjs +1 -0
- package/engine/note-dates.mjs +314 -64
- package/engine/note-package.mjs +5 -25
- package/engine/note-state.mjs +6 -2
- package/engine/note-vocabulary.mjs +74 -19
- package/engine/number-words.mjs +75 -0
- package/engine/office-holders.mjs +188 -0
- package/engine/pack-config.mjs +2 -15
- package/engine/pack-router.mjs +24 -5
- package/engine/packages.mjs +3 -2
- package/engine/pathnames.mjs +21 -24
- package/engine/pdf-build.mjs +217 -55
- package/engine/pdf-fonts.mjs +2 -2
- package/engine/pdf-images.mjs +82 -0
- package/engine/pdf-render.mjs +174 -22
- package/engine/populations.mjs +3 -2
- package/engine/project-init.mjs +499 -0
- package/engine/prose-config.mjs +1 -1
- package/engine/prose-lint.mjs +7 -6
- package/engine/readability-lint.mjs +86 -0
- package/engine/reckoning-markers.mjs +176 -166
- package/engine/scenes.mjs +5 -2
- package/engine/schema-check.mjs +3 -3
- package/engine/site-build.mjs +87 -37
- package/engine/site-config.mjs +8 -8
- package/engine/site-index.mjs +4 -0
- package/engine/site-maps.mjs +1 -1
- package/engine/site-preview.mjs +19 -8
- package/engine/social-ties.mjs +5 -1
- package/engine/sql-tables.mjs +92 -22
- package/engine/web-wikilinks.mjs +15 -31
- package/engine/wikilink-syntax.mjs +4 -1
- package/engine/wikilinks.mjs +12 -14
- package/hm3/item-fields.mjs +1 -1
- package/hm3/items.mjs +12 -45
- package/index.mjs +2 -14
- package/manifest.mjs +31 -4
- package/markdownlint-config.mjs +1 -1
- package/package.json +32 -11
- package/prettier-config.mjs +1 -1
- package/sohl/being-info.mjs +3 -145
- package/sohl/index.mjs +1 -1
- package/sohl/infobox.mjs +2 -1
- package/sohl/item-builders.mjs +3 -27
- package/sohl/item-fields.mjs +61 -22
- package/sohl/kb-passes.mjs +2 -2
- package/sohl/note-schemas.mjs +0 -8
- package/stage.mjs +19 -0
- package/types/config.d.mts +12 -3
- package/types/content-config.d.mts +15 -81
- package/types/engine/address-render.d.mts +13 -0
- package/types/engine/address.d.mts +2 -11
- package/types/engine/anchors.d.mts +3 -4
- package/types/engine/asset-bindings.d.mts +9 -2
- package/types/engine/base-compiler.d.mts +1 -2
- package/types/engine/being-measurements.d.mts +16 -0
- package/types/engine/calendar-choice.d.mts +14 -0
- package/types/engine/calendar-format.d.mts +33 -0
- package/types/engine/calendar-human.d.mts +4 -0
- package/types/engine/calendar-notes.d.mts +5 -3
- package/types/engine/calendars.d.mts +5 -3
- package/types/engine/code-fences.d.mts +6 -72
- package/types/engine/compile-corpus.d.mts +1 -3
- package/types/engine/content-admonitions.d.mts +24 -0
- package/types/engine/content-captions.d.mts +45 -0
- package/types/engine/content-footnotes.d.mts +10 -0
- package/types/engine/content-format-check.d.mts +17 -4
- package/types/engine/content-format.d.mts +24 -11
- package/types/engine/content-icons.d.mts +14 -23
- package/types/engine/content-images.d.mts +2 -2
- package/types/engine/content-index.d.mts +9 -2
- package/types/engine/content-links.d.mts +3 -5
- package/types/engine/content-tables.d.mts +11 -140
- package/types/engine/culture-choice.d.mts +14 -0
- package/types/engine/date-conversion.d.mts +4 -0
- package/types/engine/declaration-check.d.mts +24 -0
- package/types/engine/docs-checks.d.mts +28 -0
- package/types/engine/documentation-links.d.mts +7 -0
- package/types/engine/exported-scene.d.mts +6 -2
- package/types/engine/extension-attributes.d.mts +14 -0
- package/types/engine/field-spec.d.mts +9 -0
- package/types/engine/format-generated.d.mts +7 -0
- package/types/engine/frontmatter.d.mts +14 -4
- package/types/engine/generate.d.mts +1 -1
- package/types/engine/helpers.d.mts +37 -92
- package/types/engine/homepage.d.mts +2 -3
- package/types/engine/index.d.mts +5 -0
- package/types/engine/infobox-registry.d.mts +3 -1
- package/types/engine/infobox.d.mts +17 -6
- package/types/engine/item-compiler.d.mts +4 -4
- package/types/engine/item-docs.d.mts +4 -3
- package/types/engine/journals.d.mts +10 -7
- package/types/engine/map-graphviz.d.mts +1 -1
- package/types/engine/markdown-expressions.d.mts +17 -0
- package/types/engine/note-dates.d.mts +47 -1
- package/types/engine/note-package.d.mts +3 -19
- package/types/engine/note-state.d.mts +2 -1
- package/types/engine/note-vocabulary.d.mts +9 -0
- package/types/engine/number-words.d.mts +4 -0
- package/types/engine/office-holders.d.mts +14 -0
- package/types/engine/pack-config.d.mts +1 -1
- package/types/engine/packages.d.mts +3 -2
- package/types/engine/pdf-images.d.mts +38 -0
- package/types/engine/populations.d.mts +2 -2
- package/types/engine/project-init.d.mts +17 -0
- package/types/engine/prose-config.d.mts +1 -1
- package/types/engine/prose-lint.d.mts +3 -2
- package/types/engine/readability-lint.d.mts +22 -0
- package/types/engine/reckoning-markers.d.mts +13 -26
- package/types/engine/schema-check.d.mts +3 -3
- package/types/engine/site-build.d.mts +38 -28
- package/types/engine/site-config.d.mts +2 -2
- package/types/engine/site-index.d.mts +4 -0
- package/types/engine/site-preview.d.mts +1 -1
- package/types/engine/social-ties.d.mts +8 -2
- package/types/engine/sql-tables.d.mts +13 -2
- package/types/engine/web-wikilinks.d.mts +2 -1
- package/types/engine/wikilinks.d.mts +7 -1
- package/types/hm3/items.d.mts +5 -6
- package/types/labels.d.mts +40 -0
- package/types/manifest.d.mts +3 -3
- package/types/sohl/actors.d.mts +2 -2
- package/types/sohl/being-info.d.mts +3 -43
- package/types/sohl/index.d.mts +1 -1
- package/types/sohl/infobox.d.mts +5 -2
- package/types/sohl/item-fields.d.mts +4 -13
- package/types/stage.d.mts +9 -0
- 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)
|