@typeroll/mcp-server 0.42.2 → 0.43.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/AGENTS.md +25 -4
- package/README.md +14 -7
- package/dist/bundled-content.js +7 -7
- package/dist/tools/collections.js +6 -1
- package/dist/tools/migration.js +19 -2
- package/dist/tools/pages.js +2 -3
- package/dist/tools/partials.js +17 -2
- package/dist/tools/settings.js +8 -0
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/skills/tr-blog.md +36 -70
- package/skills/tr-collection-template.md +40 -3
- package/skills/tr-header-footer.md +100 -169
- package/skills/tr-migrate-wp.md +8 -0
- package/skills/tr-new-site.md +19 -37
|
@@ -1,182 +1,113 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: tr-header-footer
|
|
3
|
-
description:
|
|
3
|
+
description: Build accessible native header and footer partials with the site logo, semantic navigation, responsive disclosure, and optional native cookie consent.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
6
|
+
# Native header and footer compositions
|
|
7
|
+
|
|
8
|
+
Use block-mode partials for new work. Core 0.1.8 / capability contract 0.43.0
|
|
9
|
+
ships `template/site_logo`, `core/navigation`, layout primitives, and a
|
|
10
|
+
revision-safe partial mode operation. HTML partials remain supported for
|
|
11
|
+
legacy markup, but generic navigation and responsive layout no longer require
|
|
12
|
+
tenant HTML, CSS, or JavaScript.
|
|
13
|
+
|
|
14
|
+
## Preconditions
|
|
15
|
+
|
|
16
|
+
1. Read `get_site_capabilities`, `read_site_settings`, `list_partials`, and
|
|
17
|
+
`list_block_types`.
|
|
18
|
+
2. Require `supports_native_navigation`, `supports_partial_mode_switching`,
|
|
19
|
+
`supports_responsive_data_fields`, and
|
|
20
|
+
`supports_versioned_block_type_inheritance`.
|
|
21
|
+
3. Read the existing header/footer before replacing anything. Work in a branch
|
|
22
|
+
for redesigns and preview at desktop, 390 px, keyboard-only, and 200% zoom.
|
|
23
|
+
|
|
24
|
+
## Header tree
|
|
25
|
+
|
|
26
|
+
Stage this tree with `update_partial partial_id="header" patch={blocks:[...]}
|
|
27
|
+
save=true`, then call `set_partial_mode partial_id="header" to="blocks"` and
|
|
28
|
+
read it back. Localize both accessible labels and every link label.
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
[
|
|
32
|
+
{
|
|
33
|
+
"type": "core/section",
|
|
34
|
+
"data": { "width": "wide", "padding_y": "sm" },
|
|
35
|
+
"children": [{
|
|
36
|
+
"type": "core/container",
|
|
37
|
+
"data": {
|
|
38
|
+
"direction": { "mobile": "column", "tablet": "row" },
|
|
39
|
+
"align_main": "space-between",
|
|
40
|
+
"align_cross": "center",
|
|
41
|
+
"gap": "md",
|
|
42
|
+
"width": "wide",
|
|
43
|
+
"padding_y": "none",
|
|
44
|
+
"padding_x": "none"
|
|
45
|
+
},
|
|
46
|
+
"children": [
|
|
47
|
+
{ "type": "template/site_logo", "data": { "height": "md", "link_to_home": true } },
|
|
48
|
+
{
|
|
49
|
+
"type": "core/navigation",
|
|
50
|
+
"data": {
|
|
51
|
+
"aria_label": "Main navigation",
|
|
52
|
+
"menu_label": "Menu",
|
|
53
|
+
"links": [
|
|
54
|
+
{ "label": "Home", "href": "/" },
|
|
55
|
+
{ "label": "About", "href": "/about/" },
|
|
56
|
+
{ "label": "Contact", "href": "/contact/" }
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
}]
|
|
62
|
+
}
|
|
63
|
+
]
|
|
54
64
|
```
|
|
55
65
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
<style>
|
|
81
|
-
.tr-hdr--nav{background:var(--color-surface,#fff);border-bottom:1px solid rgba(0,0,0,.06)}
|
|
82
|
-
.tr-hdr-inner{max-width:1160px;margin:0 auto;padding:.9rem 1.5rem;display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap}
|
|
83
|
-
.tr-hdr-logo{line-height:0}
|
|
84
|
-
.tr-hdr-logo img{height:clamp(36px,4.6vw,50px);width:auto;display:block}
|
|
85
|
-
.tr-hdr-nav{display:flex;align-items:center;gap:clamp(1rem,2.4vw,2rem);font-family:var(--font-heading),sans-serif;font-weight:600}
|
|
86
|
-
.tr-hdr-nav a{color:var(--color-text,#1a1a1a);text-decoration:none}
|
|
87
|
-
.tr-hdr-nav a:hover{color:var(--color-primary,#1F4FB8)}
|
|
88
|
-
.tr-hdr-cta{background:var(--color-primary,#1F4FB8);color:var(--color-primary-fg,#fff);padding:.6rem 1.2rem;border-radius:999px}
|
|
89
|
-
.tr-hdr-cta:hover{filter:brightness(1.05);color:var(--color-primary-fg,#fff)}
|
|
90
|
-
.tr-nav-toggle{display:none}
|
|
91
|
-
.tr-nav-burger{display:none;flex-direction:column;gap:5px;cursor:pointer;padding:.4rem}
|
|
92
|
-
.tr-nav-burger span{width:24px;height:2px;background:var(--color-text,#1a1a1a);border-radius:2px}
|
|
93
|
-
@media(max-width:760px){
|
|
94
|
-
.tr-nav-burger{display:flex}
|
|
95
|
-
.tr-hdr-nav{flex-basis:100%;flex-direction:column;align-items:stretch;gap:.2rem;max-height:0;overflow:hidden;transition:max-height .25s ease}
|
|
96
|
-
.tr-hdr-nav a{padding:.7rem .2rem}
|
|
97
|
-
.tr-nav-toggle:checked ~ .tr-hdr-nav{max-height:60vh}
|
|
66
|
+
`core/navigation` emits a real `nav` and list in initial HTML, marks the
|
|
67
|
+
matching page with `aria-current="page"`, and progressively enhances to a
|
|
68
|
+
button-controlled mobile menu. Verify Tab and Shift-Tab order, Enter/Space,
|
|
69
|
+
Escape returning focus to the disclosure, visible focus, long translated
|
|
70
|
+
labels, and no horizontal overflow. Without JavaScript the links remain
|
|
71
|
+
visible and usable.
|
|
72
|
+
|
|
73
|
+
## Footer tree and consent
|
|
74
|
+
|
|
75
|
+
Use the same tree for `footer`, normally with `padding_y: "lg"`, a small site
|
|
76
|
+
logo, localized footer navigation, and optional contact/prose blocks. The
|
|
77
|
+
footer navigation gets its own accessible label; it is not the main
|
|
78
|
+
navigation landmark.
|
|
79
|
+
|
|
80
|
+
Cookie consent is a site feature, not a footer widget. Configure it separately:
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"cookie_consent": {
|
|
85
|
+
"enabled": true,
|
|
86
|
+
"text": "We use optional cookies. <a href=\"/privacy/\">Privacy policy</a>",
|
|
87
|
+
"privacy_policy_url": "/privacy/",
|
|
88
|
+
"reload_after_consent": false
|
|
89
|
+
}
|
|
98
90
|
}
|
|
99
|
-
</style>
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
**Why it's robust:** the mobile menu is a pure-CSS checkbox toggle — no JS to break,
|
|
103
|
-
no library. The `overflow:hidden` is ONLY on the collapsing nav list (never on the
|
|
104
|
-
header or the logo), so the logo is always fully visible. Links use site colour
|
|
105
|
-
variables so it matches the brand automatically. The header wraps (`flex-wrap`) so
|
|
106
|
-
nothing overflows the viewport on narrow screens.
|
|
107
|
-
|
|
108
|
-
---
|
|
109
|
-
|
|
110
|
-
## Footer A — Centered minimal
|
|
111
|
-
|
|
112
|
-
```html
|
|
113
|
-
<footer class="tr-ftr tr-ftr--center">
|
|
114
|
-
<div class="tr-ftr-inner">
|
|
115
|
-
<div class="tr-ftr-brand">{{SITE_NAME}}</div>
|
|
116
|
-
<p class="tr-ftr-tag">{{TAGLINE}}</p>
|
|
117
|
-
<p class="tr-ftr-contact"><a href="mailto:{{EMAIL}}">{{EMAIL}}</a></p>
|
|
118
|
-
<p class="tr-ftr-copy">© {{YEAR}} {{SITE_NAME}}</p>
|
|
119
|
-
</div>
|
|
120
|
-
</footer>
|
|
121
|
-
<style>
|
|
122
|
-
.tr-ftr--center{background:var(--color-primary,#163C8C);color:rgba(255,255,255,.78)}
|
|
123
|
-
.tr-ftr--center .tr-ftr-inner{max-width:1120px;margin:0 auto;padding:2.6rem 1.5rem;text-align:center;display:grid;gap:.45rem}
|
|
124
|
-
.tr-ftr-brand{font-family:var(--font-heading),sans-serif;font-weight:800;font-size:1.35rem;color:#fff}
|
|
125
|
-
.tr-ftr-tag{margin:0;font-size:1rem;color:rgba(255,255,255,.85)}
|
|
126
|
-
.tr-ftr-contact{margin:.15rem 0 0}
|
|
127
|
-
.tr-ftr-contact a{color:#fff;text-decoration:none;font-weight:600}
|
|
128
|
-
.tr-ftr-contact a:hover{text-decoration:underline}
|
|
129
|
-
.tr-ftr-copy{margin:.8rem 0 0;font-size:.85rem;color:rgba(255,255,255,.55)}
|
|
130
|
-
</style>
|
|
131
91
|
```
|
|
132
92
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
<div class="tr-ftr-grid">
|
|
138
|
-
<div class="tr-ftr-col">
|
|
139
|
-
<div class="tr-ftr-brand">{{SITE_NAME}}</div>
|
|
140
|
-
<p class="tr-ftr-tag">{{TAGLINE}}</p>
|
|
141
|
-
</div>
|
|
142
|
-
<nav class="tr-ftr-col" aria-label="Sidfot">
|
|
143
|
-
<a href="/">Start</a>
|
|
144
|
-
<a href="#">Sidan ett</a>
|
|
145
|
-
<a href="#">Sidan två</a>
|
|
146
|
-
</nav>
|
|
147
|
-
<div class="tr-ftr-col">
|
|
148
|
-
<p class="tr-ftr-contact"><a href="mailto:{{EMAIL}}">{{EMAIL}}</a></p>
|
|
149
|
-
</div>
|
|
150
|
-
</div>
|
|
151
|
-
<p class="tr-ftr-copy">© {{YEAR}} {{SITE_NAME}}</p>
|
|
152
|
-
</footer>
|
|
153
|
-
<style>
|
|
154
|
-
.tr-ftr--cols{background:var(--color-primary,#163C8C);color:rgba(255,255,255,.78)}
|
|
155
|
-
.tr-ftr--cols .tr-ftr-grid{max-width:1120px;margin:0 auto;padding:3rem 1.5rem 1.4rem;display:grid;grid-template-columns:1.4fr 1fr 1fr;gap:2rem}
|
|
156
|
-
.tr-ftr--cols .tr-ftr-brand{font-family:var(--font-heading),sans-serif;font-weight:800;font-size:1.35rem;color:#fff;margin-bottom:.4rem}
|
|
157
|
-
.tr-ftr--cols .tr-ftr-tag{margin:0;color:rgba(255,255,255,.8);max-width:34ch}
|
|
158
|
-
.tr-ftr--cols .tr-ftr-col{display:grid;gap:.5rem;align-content:start}
|
|
159
|
-
.tr-ftr--cols nav a{color:rgba(255,255,255,.85);text-decoration:none}
|
|
160
|
-
.tr-ftr--cols nav a:hover{color:#fff;text-decoration:underline}
|
|
161
|
-
.tr-ftr-contact a{color:#fff;text-decoration:none;font-weight:600}
|
|
162
|
-
.tr-ftr--cols .tr-ftr-copy{max-width:1120px;margin:0 auto;padding:0 1.5rem 2.4rem;font-size:.85rem;color:rgba(255,255,255,.55)}
|
|
163
|
-
@media(max-width:680px){.tr-ftr--cols .tr-ftr-grid{grid-template-columns:1fr;gap:1.4rem}}
|
|
164
|
-
</style>
|
|
165
|
-
```
|
|
93
|
+
Use `update_site_settings`, then read settings back. `scripts_necessary` and
|
|
94
|
+
`scripts_optional` execute in visitors' browsers and must be reviewed like
|
|
95
|
+
other API-key-authorized script surfaces. Verify accept/necessary/reject,
|
|
96
|
+
optional-script gating, and keyboard focus in preview and the actual build.
|
|
166
97
|
|
|
167
|
-
|
|
168
|
-
horizontal scroll); all colours come from `--color-*` with fallbacks; the contact
|
|
169
|
-
is a real `mailto:` link; nothing relies on fixed heights. Swap `--color-primary`
|
|
170
|
-
for a custom dark if the brand's primary is too light for white text.
|
|
98
|
+
## Version and dependency rules
|
|
171
99
|
|
|
172
|
-
|
|
100
|
+
Child versions inherit installed, custom, and third-party block types from
|
|
101
|
+
their base chain. If preview reports a missing type, stop and inspect
|
|
102
|
+
`list_block_types` for that exact version; do not duplicate an Extension or
|
|
103
|
+
installation. A type missing after capability 0.43.0 is a dependency error to
|
|
104
|
+
report, not a reason to let the block silently disappear.
|
|
173
105
|
|
|
174
|
-
##
|
|
106
|
+
## Final checks
|
|
175
107
|
|
|
176
|
-
-
|
|
177
|
-
|
|
178
|
-
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
-
|
|
182
|
-
linking to `/`.
|
|
108
|
+
- Header and footer landmarks exist exactly once around their content.
|
|
109
|
+
- Logo is fully visible, keeps its aspect ratio, has useful alt text, and links home.
|
|
110
|
+
- Current-page state and localized navigation labels are correct.
|
|
111
|
+
- Mobile disclosure is keyboard accessible and does not trap focus.
|
|
112
|
+
- No tenant CSS is required for spacing, focus, wrapping, or the narrow layout.
|
|
113
|
+
- Preview and a hosted static build match before promotion.
|
package/skills/tr-migrate-wp.md
CHANGED
|
@@ -26,6 +26,14 @@ agency) reviews each step in their terminal.
|
|
|
26
26
|
get_migration_readiness source_url="https://oldsite.com"
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
+
When the migration includes reusable page/item layouts, include each proposed
|
|
30
|
+
block composition and its collection fields in this same call. A
|
|
31
|
+
`waiting_for_native_support` result means leave that template intact and do
|
|
32
|
+
not replace the gap with generic custom blocks, raw HTML, or corrective site
|
|
33
|
+
CSS. Independent content and SEO work may continue. Rerun the review after the
|
|
34
|
+
required Core version is deployed, then verify preview and a fresh hosted
|
|
35
|
+
build.
|
|
36
|
+
|
|
29
37
|
Pass `source_url` — that adds the checks on the site you're migrating FROM.
|
|
30
38
|
An old host that answers 403/429 to server-side requests is a **blocker**: the
|
|
31
39
|
import would produce empty pages, or pages containing the host's block page,
|
package/skills/tr-new-site.md
CHANGED
|
@@ -57,9 +57,9 @@ Common requirements that are easy to misclassify:
|
|
|
57
57
|
| Responsive icon/card grid | `core/grid` + `core/icon_box`, or `core/feature_grid`; set responsive fields with `set_block_responsive` |
|
|
58
58
|
| Custom cards backed by a collection | `core/repeater` / `core/collection_list` with a site-authored `item_compatible` block type as `item_block` |
|
|
59
59
|
| Grouped collection listing | `core/repeater` with `group_by`; array-valued fields place an item in every matching group |
|
|
60
|
-
| Breadcrumbs in a page template | `template/page_breadcrumbs
|
|
61
|
-
| Generated heading index | `core/table_of_contents`; choose
|
|
62
|
-
| Previous/next collection item links | `template/item_navigation
|
|
60
|
+
| Breadcrumbs in a page template | `template/page_breadcrumbs`; page and item routes supply a server-rendered trail |
|
|
61
|
+
| Generated heading index | `core/table_of_contents`; choose heading levels and set `source_field` for collection content |
|
|
62
|
+
| Previous/next collection item links | `template/item_navigation`; defaults to collection order and can bind explicit neighbor fields |
|
|
63
63
|
| Download CTA that disappears without a file | `template/show_if` around a context-bound `core/button`; a dedicated download block is only editor convenience |
|
|
64
64
|
| Sticky/custom header and multi-column footer | Block-mode header/footer partials plus layout blocks, or one reusable custom block type |
|
|
65
65
|
| Cookie notice | `settings.cookie_consent`, not a page block |
|
|
@@ -115,40 +115,22 @@ an iframe cannot be represented.
|
|
|
115
115
|
|
|
116
116
|
### 3. Header + footer partials
|
|
117
117
|
|
|
118
|
-
**Start from
|
|
119
|
-
tr-header-footer`
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
```html
|
|
131
|
-
<header class="site-header">
|
|
132
|
-
<div class="header-inner">
|
|
133
|
-
<a class="header-logo" href="/"><img src="LOGO_MEDIA_URL" alt="Acme Studio" height="40" /></a>
|
|
134
|
-
<nav class="header-nav">
|
|
135
|
-
<a href="/om-oss">Om oss</a>
|
|
136
|
-
<a href="/kontakt">Kontakt</a>
|
|
137
|
-
</nav>
|
|
138
|
-
</div>
|
|
139
|
-
</header>
|
|
140
|
-
<style>
|
|
141
|
-
.site-header{background:var(--color-background);padding:1rem 2rem}
|
|
142
|
-
.header-inner{max-width:1080px;margin:0 auto;display:flex;align-items:center;justify-content:space-between}
|
|
143
|
-
.header-nav{display:flex;gap:2rem}
|
|
144
|
-
.header-nav a{color:var(--color-text);text-decoration:none}
|
|
145
|
-
</style>
|
|
146
|
-
```
|
|
118
|
+
**Start from the native preset — don't hand-roll navigation.** Read
|
|
119
|
+
`tr-header-footer` and use its `template/site_logo` + `core/navigation`
|
|
120
|
+
composition. The server-rendered landmark, current-page state, no-JS links,
|
|
121
|
+
mobile disclosure, focus treatment, and responsive behavior are Core
|
|
122
|
+
contracts rather than tenant CSS/JavaScript.
|
|
123
|
+
|
|
124
|
+
Stage the complete tree with `update_partial partial_id="header"
|
|
125
|
+
patch={blocks:[...]} save=true`, then call `set_partial_mode partial_id="header"
|
|
126
|
+
to="blocks"`. Repeat for the footer and read both partials back. The inactive
|
|
127
|
+
HTML representation is retained for rollback; changing `content_mode` through
|
|
128
|
+
ordinary PATCH/PUT is rejected intentionally.
|
|
147
129
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
130
|
+
Use HTML mode only when preserving legacy authored markup that cannot yet be
|
|
131
|
+
represented natively. Partials receive the same `{{site.*}}` render context as
|
|
132
|
+
page blocks. Keep the first section and header backgrounds intentional; do not
|
|
133
|
+
add a decorative border merely to compensate for mismatched spacing.
|
|
152
134
|
|
|
153
135
|
### 4. Homepage — block tree
|
|
154
136
|
|
|
@@ -181,7 +163,7 @@ on a block *inside* the section instead):
|
|
|
181
163
|
] },
|
|
182
164
|
{ "type": "core/section", "data": { "padding_y": "lg" }, "children": [
|
|
183
165
|
{ "type": "core/heading", "data": { "text": "Så funkar det", "level": "h2", "align": "center" } },
|
|
184
|
-
{ "type": "core/grid", "data": { "cols": 3, "gap": "lg" }, "children": [
|
|
166
|
+
{ "type": "core/grid", "data": { "cols": { "mobile": 1, "tablet": 2, "desktop": 3 }, "gap": "lg" }, "children": [
|
|
185
167
|
{ "type": "core/step_card", "data": { "number": "1", "title": "…", "text": "<p>…</p>" } },
|
|
186
168
|
{ "type": "core/step_card", "data": { "number": "2", "title": "…", "text": "<p>…</p>" } },
|
|
187
169
|
{ "type": "core/step_card", "data": { "number": "3", "title": "…", "text": "<p>…</p>" } }
|