@taprootio/site-authoring 0.1.1 → 0.3.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/README.md CHANGED
@@ -39,8 +39,8 @@ resolve a different contract than the CLI was tested against.
39
39
  `taproot-site --help` lists every verb and the configuration contract.
40
40
  `taproot-site help` is the offline reference family agents read before
41
41
  authoring: page types, components, navigation, media, previews, themes,
42
- appearance, and the footer, each with `--json` for stable machine-readable
43
- output.
42
+ appearance, the footer, and the offline fixture contract, each with `--json`
43
+ for stable machine-readable output.
44
44
 
45
45
  ```bash
46
46
  taproot-site help
@@ -58,6 +58,23 @@ appearance, header, brand, and footer, and fixture-local image identities. It
58
58
  does not prove authorization, site ownership, concurrency, server round trips,
59
59
  or rendering; a real pull and an authorized preview do that.
60
60
 
61
+ The package ships one, so `validate` is runnable the moment the install
62
+ finishes. `taproot-site help fixture` states the manifest contract and prints
63
+ the shipped fixture's absolute path along with the exact command to validate
64
+ it:
65
+
66
+ ```bash
67
+ taproot-site help fixture
68
+ taproot-site validate "$(npm root --global)/@taprootio/site-authoring/examples/riverbend-wellness"
69
+ ```
70
+
71
+ The fixture is a fictional wellness studio — `example.test` hostnames, a
72
+ reserved `555-01xx` telephone number, an invented street and town — with two
73
+ free-form pages, a three-item navigation tree, and all four settings
74
+ documents. Nothing in it describes a real business. Copy the directory
75
+ somewhere writable before you edit it; `validate` never writes to the fixture
76
+ it reads.
77
+
61
78
  ## Authorize
62
79
 
63
80
  Sign in once. `login` starts a device-style authorization: it prints an
@@ -208,11 +225,15 @@ whose approval code and URL exist only as progress). Stdout carries exactly
208
225
  one JSON object per run, schema version `1`: `ok`, the CLI name and version,
209
226
  the verb, and the verb's own result on success; a stable `error.code` with an
210
227
  optional `field`, `status`, and classified `refusal` on failure. Exit codes are
211
- `0` success, `1` failure, and `2` usage fault. The four refusal classes an
228
+ `0` success, `1` failure, and `2` usage fault. The five refusal classes an
212
229
  automation should branch on are `platform_paused` (external authoring is
213
230
  paused; retry later), `credential_rejected` (stop and re-issue),
214
- `plan_limit` (the plan's published-page allowance, surfaced at deploy), and
215
- `throttled` (back off).
231
+ `capability_missing` (the credential is valid and correctly scoped but was
232
+ not exchanged for a capability the request needs; the refusal carries
233
+ `field: "GrantedCapabilities"`, and the CLI's human progress names the
234
+ granted and required capabilities, so report the verb's declared set rather
235
+ than re-issuing the key), `plan_limit` (the plan's published-page allowance,
236
+ surfaced at deploy), and `throttled` (back off).
216
237
 
217
238
  When `GITHUB_OUTPUT` names the runner's existing output file, every
218
239
  operational verb appends the same JSON under `taproot_site_result` through a
@@ -0,0 +1,74 @@
1
+ {
2
+ "manifestVersion": 5,
3
+ "siteId": "a0000000-0000-4000-8000-000000000001",
4
+ "pulledAt": "2026-09-04T00:00:00.000Z",
5
+ "pages": [
6
+ {
7
+ "pageId": "a0000000-0000-4000-8000-000000000010",
8
+ "resourceId": "a0000000-0000-4000-8000-000000000011",
9
+ "path": "",
10
+ "title": "Riverbend Wellness",
11
+ "status": "PAGE_STATUS_DRAFT",
12
+ "templateType": "TEMPLATE_TYPE_FREE_FORM",
13
+ "hasDraft": true,
14
+ "isGenerated": false,
15
+ "description": "An example home page for the offline authoring fixture.",
16
+ "file": "pages/index.md",
17
+ "sourceFormat": "markdown",
18
+ "workspaceMode": "editable"
19
+ },
20
+ {
21
+ "pageId": "a0000000-0000-4000-8000-000000000012",
22
+ "resourceId": "a0000000-0000-4000-8000-000000000013",
23
+ "path": "visit",
24
+ "title": "Visit the studio",
25
+ "status": "PAGE_STATUS_DRAFT",
26
+ "templateType": "TEMPLATE_TYPE_FREE_FORM",
27
+ "hasDraft": true,
28
+ "isGenerated": false,
29
+ "description": "An example second page for the offline authoring fixture.",
30
+ "file": "pages/visit.md",
31
+ "sourceFormat": "markdown",
32
+ "workspaceMode": "editable"
33
+ }
34
+ ],
35
+ "pagesTruncated": false,
36
+ "navigation": {
37
+ "file": "nav.json",
38
+ "items": 3
39
+ },
40
+ "settings": [
41
+ {
42
+ "settingsType": "SETTING_TYPE_TAPROOT_STYLES",
43
+ "file": "settings/taproot-styles.json",
44
+ "entityId": "a0000000-0000-4000-8000-000000000020"
45
+ },
46
+ {
47
+ "settingsType": "SETTING_TYPE_BRAND",
48
+ "file": "settings/brand.json",
49
+ "entityId": "a0000000-0000-4000-8000-000000000021"
50
+ },
51
+ {
52
+ "settingsType": "SETTING_TYPE_SITE_HEADER",
53
+ "file": "settings/site-header.json",
54
+ "entityId": "a0000000-0000-4000-8000-000000000022"
55
+ },
56
+ {
57
+ "settingsType": "SETTING_TYPE_SITE_PUBLISHING_PREFERENCES",
58
+ "file": "settings/site-publishing-preferences.json",
59
+ "entityId": "a0000000-0000-4000-8000-000000000023"
60
+ }
61
+ ],
62
+ "settingsSkipped": [],
63
+ "fixture": {
64
+ "contractVersion": 1,
65
+ "imageIds": [
66
+ "a0000000-0000-4000-8000-0000000000a0",
67
+ "a0000000-0000-4000-8000-0000000000a1",
68
+ "a0000000-0000-4000-8000-0000000000a2"
69
+ ],
70
+ "deliveryOrigins": [
71
+ "https://static.example.test"
72
+ ]
73
+ }
74
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "siteId": "a0000000-0000-4000-8000-000000000001",
3
+ "navItems": [
4
+ {
5
+ "id": "a0000000-0000-4000-8000-000000000030",
6
+ "kind": "NAV_ITEM_KIND_PAGE",
7
+ "title": "Home",
8
+ "resourceId": "a0000000-0000-4000-8000-000000000011",
9
+ "children": []
10
+ },
11
+ {
12
+ "id": "a0000000-0000-4000-8000-000000000031",
13
+ "kind": "NAV_ITEM_KIND_PAGE",
14
+ "title": "Visit",
15
+ "resourceId": "a0000000-0000-4000-8000-000000000013",
16
+ "children": []
17
+ },
18
+ {
19
+ "id": "a0000000-0000-4000-8000-000000000032",
20
+ "kind": "NAV_ITEM_KIND_EXTERNAL_URL",
21
+ "title": "Book a class",
22
+ "externalUrl": "https://schedule.example.test/riverbend",
23
+ "children": []
24
+ }
25
+ ]
26
+ }
@@ -0,0 +1,93 @@
1
+ ---
2
+ title: Riverbend Wellness
3
+ path: ""
4
+ description: An example home page for the offline authoring fixture.
5
+ ---
6
+
7
+ ```component:hero-section
8
+ {
9
+ "overline": "Riverbend Wellness · Elm Harbor",
10
+ "title": "An example site you can validate before you have one.",
11
+ "titleSize": "display",
12
+ "lead": "Riverbend Wellness is invented. It exists so taproot-site validate has a complete workspace to check on a machine that has never pulled a real site.",
13
+ "primaryAction": {
14
+ "label": "Visit the studio",
15
+ "url": "/visit"
16
+ },
17
+ "secondaryAction": {
18
+ "label": "Book a class",
19
+ "url": "https://schedule.example.test/riverbend"
20
+ },
21
+ "alignment": "start",
22
+ "media": {
23
+ "imageId": "a0000000-0000-4000-8000-0000000000a2",
24
+ "src": "https://static.example.test/site/img/riverbend-studio-1280.webp",
25
+ "urls": [
26
+ {
27
+ "minWidth": 640,
28
+ "url": "https://static.example.test/site/img/riverbend-studio-640.webp"
29
+ },
30
+ {
31
+ "minWidth": 1280,
32
+ "url": "https://static.example.test/site/img/riverbend-studio-1280.webp"
33
+ }
34
+ ],
35
+ "width": 1600,
36
+ "height": 1067,
37
+ "alt": "An example photograph placeholder for the fixture studio"
38
+ },
39
+ "mediaArrangement": "split",
40
+ "mediaPosition": "after",
41
+ "mediaWidth": "equal"
42
+ }
43
+ ```
44
+
45
+ :::section {"context":"subtle","contentPadding":"standard","surface":"none"}
46
+ ## What this fixture is for
47
+
48
+ Every value here is fictional. The studio, the street, the telephone number,
49
+ and the image delivery host are all invented, and the image identities are
50
+ declared in `manifest.fixture.json` under the `fixture` block so `validate`
51
+ can bind them without a network.
52
+
53
+ Run `taproot-site help fixture` for the manifest contract this directory
54
+ follows, and `taproot-site help page free-form` for the document vocabulary
55
+ these pages are written in.
56
+
57
+ ```inline-facts
58
+ [
59
+ {
60
+ "value": "2 pages",
61
+ "label": "Free-form sources"
62
+ },
63
+ {
64
+ "value": "(555) 555-0147",
65
+ "label": "Reserved example number",
66
+ "url": "tel:+15555550147"
67
+ },
68
+ {
69
+ "value": "12 Alder Street, Elm Harbor",
70
+ "label": "Invented address"
71
+ }
72
+ ]
73
+ ```
74
+ :::
75
+
76
+ :::section {"context":"inverted","contentPadding":"standard","surface":"none"}
77
+ ## Change one thing and watch it fail
78
+
79
+ The fastest way to learn the contract is to break it. Point a navigation item
80
+ at a resource identity this fixture does not declare, or set
81
+ `defaultScheme` to a value outside `system`, `light`, and `dark`, and
82
+ `validate` names the file and the field it refused.
83
+
84
+ ```component:cta
85
+ {
86
+ "heading": "Then put it back.",
87
+ "description": "Copy this directory somewhere writable before you edit it; validate never writes to the fixture it reads.",
88
+ "buttonText": "Visit the studio",
89
+ "buttonUrl": "/visit",
90
+ "variant": "primary"
91
+ }
92
+ ```
93
+ :::
@@ -0,0 +1,33 @@
1
+ ---
2
+ title: Visit the studio
3
+ path: visit
4
+ description: An example second page for the offline authoring fixture.
5
+ ---
6
+
7
+ :::section {"contentPadding":"standard","surface":"none"}
8
+ ## Visit the studio
9
+
10
+ Riverbend Wellness is a fictional studio in the fictional town of Elm Harbor.
11
+ Nothing on this page describes a real place, and no address, telephone number,
12
+ or hostname here resolves to one.
13
+
14
+ - **12 Alder Street, Elm Harbor** — an invented address
15
+ - **(555) 555-0147** — from the reserved example telephone range
16
+ - **hello@example.test** — a reserved example domain
17
+
18
+ This page exists so the fixture binds more than one page identity: the
19
+ navigation tree points at both, the footer links to both, and `validate`
20
+ proves every reference resolves inside the fixture.
21
+ :::
22
+
23
+ :::section {"context":"raised","contentPadding":"standard","surface":"elevated"}
24
+ ## Hours
25
+
26
+ | Day | Doors | Last class |
27
+ | --- | --- | --- |
28
+ | Monday to Friday | 6:00 AM | 7:30 PM |
29
+ | Saturday | 7:30 AM | 4:00 PM |
30
+ | Sunday | 8:00 AM | 2:00 PM |
31
+
32
+ Every figure above is invented for the fixture.
33
+ :::
@@ -0,0 +1,7 @@
1
+ {
2
+ "entityId": "a0000000-0000-4000-8000-000000000021",
3
+ "settingsType": "SETTING_TYPE_BRAND",
4
+ "settings": {
5
+ "faviconId": "a0000000-0000-4000-8000-0000000000a0"
6
+ }
7
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "entityId": "a0000000-0000-4000-8000-000000000022",
3
+ "settingsType": "SETTING_TYPE_SITE_HEADER",
4
+ "settings": {
5
+ "headerLayout": "standard",
6
+ "headerWidth": "contained",
7
+ "navDrawerStyle": "full-screen",
8
+ "navDrawerTransition": "fade",
9
+ "brandText": "Riverbend Wellness",
10
+ "logoAlt": "Riverbend Wellness",
11
+ "navMenuDisplay": "auto",
12
+ "headerPosition": "sticky",
13
+ "showThemeToggle": true,
14
+ "showBrandText": true,
15
+ "brandLogoSize": "standard",
16
+ "brandHoverGrow": false,
17
+ "brandColor": "--esp-color-headings",
18
+ "lightBrandColor": "--esp-color-headings",
19
+ "darkBrandColor": "--esp-color-headings"
20
+ }
21
+ }
@@ -0,0 +1,107 @@
1
+ {
2
+ "entityId": "a0000000-0000-4000-8000-000000000023",
3
+ "settingsType": "SETTING_TYPE_SITE_PUBLISHING_PREFERENCES",
4
+ "settings": {
5
+ "footerSettings": {
6
+ "enabled": true,
7
+ "showBrand": true,
8
+ "showBrandText": true,
9
+ "asideCta": {
10
+ "id": "a0000000-0000-4000-8000-000000000040",
11
+ "label": "Book a class",
12
+ "externalUrl": "https://schedule.example.test/riverbend"
13
+ },
14
+ "bottomLinks": [
15
+ {
16
+ "id": "a0000000-0000-4000-8000-000000000041",
17
+ "label": "Visit",
18
+ "pageResourceId": "a0000000-0000-4000-8000-000000000013"
19
+ }
20
+ ],
21
+ "light": {
22
+ "backgroundColor": "--esp-color-layer-1",
23
+ "textColor": "--esp-color-text",
24
+ "headingColor": "--esp-color-headings",
25
+ "linkColor": "--esp-color-link",
26
+ "linkHoverColor": "--esp-color-link-hover",
27
+ "backgroundImageId": "",
28
+ "backgroundImageOpacity": 0,
29
+ "backgroundPresentation": "FOOTER_BACKGROUND_PRESENTATION_COVER",
30
+ "backgroundFade": "FOOTER_FADE_MODE_NONE",
31
+ "backgroundRepeatHeightPx": 160,
32
+ "additionalTopPaddingRem": 1
33
+ },
34
+ "dark": {
35
+ "backgroundColor": "--esp-color-layer-1",
36
+ "textColor": "--esp-color-text",
37
+ "headingColor": "--esp-color-headings",
38
+ "linkColor": "--esp-color-link",
39
+ "linkHoverColor": "--esp-color-link-hover",
40
+ "backgroundImageId": "",
41
+ "backgroundImageOpacity": 0,
42
+ "backgroundPresentation": "FOOTER_BACKGROUND_PRESENTATION_COVER",
43
+ "backgroundFade": "FOOTER_FADE_MODE_NONE",
44
+ "backgroundRepeatHeightPx": 160,
45
+ "additionalTopPaddingRem": 1
46
+ },
47
+ "linkColumns": [
48
+ {
49
+ "id": "a0000000-0000-4000-8000-000000000042",
50
+ "groups": [
51
+ {
52
+ "id": "a0000000-0000-4000-8000-000000000043",
53
+ "heading": "Studio",
54
+ "links": [
55
+ {
56
+ "id": "a0000000-0000-4000-8000-000000000044",
57
+ "label": "Home",
58
+ "pageResourceId": "a0000000-0000-4000-8000-000000000011"
59
+ },
60
+ {
61
+ "id": "a0000000-0000-4000-8000-000000000045",
62
+ "label": "Visit",
63
+ "pageResourceId": "a0000000-0000-4000-8000-000000000013"
64
+ }
65
+ ]
66
+ }
67
+ ]
68
+ }
69
+ ],
70
+ "asideHeadingContent": {
71
+ "paragraphs": [
72
+ {
73
+ "runs": [
74
+ {
75
+ "text": "Everything here is invented.",
76
+ "bold": true
77
+ }
78
+ ]
79
+ }
80
+ ]
81
+ },
82
+ "asideBodyContent": {
83
+ "paragraphs": [
84
+ {
85
+ "runs": [
86
+ {
87
+ "text": "Riverbend Wellness is a fictional studio used to demonstrate the authoring contract offline."
88
+ }
89
+ ]
90
+ }
91
+ ]
92
+ },
93
+ "bottomContent": {
94
+ "paragraphs": [
95
+ {
96
+ "runs": [
97
+ {
98
+ "text": "An example fixture. Not a real business."
99
+ }
100
+ ]
101
+ }
102
+ ]
103
+ },
104
+ "featureImage": null
105
+ }
106
+ }
107
+ }