@typeroll/mcp-server 0.44.74 → 0.45.1
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 +63 -74
- package/README.md +32 -18
- package/dist/bundled-content.js +15 -16
- package/dist/init.js +6 -0
- package/dist/server.js +15 -7
- package/dist/tools/bulk.js +4 -5
- package/dist/tools/content-types.js +28 -0
- package/dist/tools/deploy.js +1 -1
- package/dist/tools/migration.js +3 -4
- package/dist/tools/page-blocks.js +2 -2
- package/dist/tools/page-templates.js +18 -0
- package/dist/tools/pages.js +16 -3
- package/dist/tools/preview.js +1 -3
- package/dist/tools/sites.js +1 -1
- package/dist/tools/working-copy.js +2 -8
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/skills/README.md +6 -7
- package/skills/tr-blog.md +46 -130
- package/skills/tr-brand.md +2 -2
- package/skills/tr-content-write.md +1 -1
- package/skills/tr-directory.md +46 -271
- package/skills/tr-import-url.md +1 -1
- package/skills/tr-migrate-astro.md +65 -293
- package/skills/tr-migrate-multisite.md +1 -1
- package/skills/tr-migrate-wp.md +2 -2
- package/skills/tr-new-site.md +9 -9
- package/skills/tr-page-template.md +53 -164
- package/skills/tr-redesign-branch.md +2 -2
- package/skills/tr-responsive.md +2 -2
- package/skills/tr-seo.md +1 -1
- package/dist/tools/collections.js +0 -242
- package/skills/tr-collection-template.md +0 -305
|
@@ -1,297 +1,69 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: tr-migrate-astro
|
|
3
|
-
description:
|
|
3
|
+
description: Migrate an existing Astro site, including Astro Content Collections, to native Typeroll Pages and Content types while preserving routes, design and media.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Migrate an Astro site
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const blog = defineCollection({
|
|
71
|
-
type: 'content',
|
|
72
|
-
schema: z.object({
|
|
73
|
-
title: z.string(),
|
|
74
|
-
description: z.string(),
|
|
75
|
-
pubDate: z.coerce.date(),
|
|
76
|
-
updatedDate: z.coerce.date().optional(),
|
|
77
|
-
heroImage: z.string().optional(),
|
|
78
|
-
author: z.string().default('Editorial'),
|
|
79
|
-
tags: z.array(z.string()).default([]),
|
|
80
|
-
draft: z.boolean().default(false),
|
|
81
|
-
}),
|
|
82
|
-
});
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
Map zod types to Typeroll field types:
|
|
86
|
-
|
|
87
|
-
| Astro zod | Typeroll field type |
|
|
88
|
-
|---|---|
|
|
89
|
-
| `z.string()` | `text` (or `textarea` if it's a description/excerpt — judge by typical length) |
|
|
90
|
-
| `z.string().long()` / a description field | `textarea` |
|
|
91
|
-
| `z.coerce.date()` / `z.date()` | `date` |
|
|
92
|
-
| `z.number()` | `number` |
|
|
93
|
-
| `z.boolean()` | `boolean` |
|
|
94
|
-
| `z.string()` with image path / `image()` helper | `image` |
|
|
95
|
-
| `z.array(z.string())` | `text` (comma-joined) or `tags` if you have a tags field type |
|
|
96
|
-
| `z.enum([...])` | `text` with a comment about the allowed values; the model writes the listing logic |
|
|
97
|
-
| `z.object({...})` (nested) | Flatten into prefixed fields, or pre-render into a `*_html` field (see `tr-collection-template`) |
|
|
98
|
-
| Markdown body | `body: richtext` (the markdown content of the file, converted to HTML — see §4) |
|
|
99
|
-
|
|
100
|
-
Create the collection with the design template baked in (this is the new pattern — read `tr-blog` if you haven't yet):
|
|
101
|
-
|
|
102
|
-
```
|
|
103
|
-
create_collection {
|
|
104
|
-
"name": "blog",
|
|
105
|
-
"label_singular": "Article",
|
|
106
|
-
"label_plural": "Articles",
|
|
107
|
-
"slug_field": "slug",
|
|
108
|
-
"sort_field": "date",
|
|
109
|
-
"sort_dir": "desc",
|
|
110
|
-
"route_template": "/blog/{slug}",
|
|
111
|
-
"fields": [
|
|
112
|
-
{"name":"title", "type":"text", "required":true},
|
|
113
|
-
{"name":"slug", "type":"text", "required":true},
|
|
114
|
-
{"name":"description", "type":"textarea"},
|
|
115
|
-
{"name":"date", "type":"date", "required":true},
|
|
116
|
-
{"name":"updated_date","type":"date"},
|
|
117
|
-
{"name":"hero_image", "type":"image"},
|
|
118
|
-
{"name":"author", "type":"text"},
|
|
119
|
-
{"name":"tags", "type":"text"},
|
|
120
|
-
{"name":"body", "type":"richtext"}
|
|
121
|
-
],
|
|
122
|
-
"item_template_html": "<article class=\"post\">...</article>"
|
|
123
|
-
}
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
Field-name rules: ASCII, lowercase, `[a-z][a-z0-9_-]*`. The Astro source `pubDate` → Typeroll `date`. `updatedDate` → `updated_date` (snake_case is fine; camelCase isn't).
|
|
127
|
-
|
|
128
|
-
### 4. Convert markdown bodies → richtext
|
|
129
|
-
|
|
130
|
-
Astro stores the markdown body as the file content after the `---` frontmatter fence. Typeroll's `body: richtext` wants HTML. Pick one of:
|
|
131
|
-
|
|
132
|
-
**Option A — use Astro's own markdown renderer (preferred when the repo already builds):**
|
|
133
|
-
|
|
134
|
-
```js
|
|
135
|
-
import { unified } from 'unified';
|
|
136
|
-
import remarkParse from 'remark-parse';
|
|
137
|
-
import remarkRehype from 'remark-rehype';
|
|
138
|
-
import rehypeStringify from 'rehype-stringify';
|
|
139
|
-
|
|
140
|
-
const md2html = async (md) => {
|
|
141
|
-
const file = await unified()
|
|
142
|
-
.use(remarkParse)
|
|
143
|
-
.use(remarkRehype, { allowDangerousHtml: true })
|
|
144
|
-
.use(rehypeStringify, { allowDangerousHtml: true })
|
|
145
|
-
.process(md);
|
|
146
|
-
return String(file);
|
|
147
|
-
};
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
Run this on the body of every collection file. Image references inside the markdown (``) need their `src` rewritten to the uploaded Typeroll CDN URLs after step 6.
|
|
151
|
-
|
|
152
|
-
**Option B — convert ad-hoc:** `marked`, `markdown-it`, or any other parser. Just stay consistent across files so the HTML output looks uniform.
|
|
153
|
-
|
|
154
|
-
Typeroll's sanitiser will strip `<script>` and event handlers from the output regardless. If the markdown carried embedded raw HTML you want to keep (iframes for video, etc.), check the sanitiser config in `packages/site-template/src/lib/sanitize.ts` for the whitelist.
|
|
155
|
-
|
|
156
|
-
### 5. Resolve and upload images
|
|
157
|
-
|
|
158
|
-
For every image referenced by an item (`heroImage`, images inside the markdown body):
|
|
159
|
-
|
|
160
|
-
1. Stage the local file at a temporary public URL (or use a local-upload MCP tool if one is configured).
|
|
161
|
-
2. `upload_media_from_url url=<staged-url> alt=<from frontmatter or filename>` — record the returned CDN URL.
|
|
162
|
-
3. Substitute the CDN URL into both the `hero_image` field value AND the markdown-converted HTML body (regex replace `src=` references).
|
|
163
|
-
|
|
164
|
-
Keep a local map (`./astro-migration-state.json`):
|
|
165
|
-
|
|
166
|
-
```json
|
|
167
|
-
{
|
|
168
|
-
"media": {
|
|
169
|
-
"./hero.png": "https://cdn.typeroll.com/<orgId>/<siteId>/abc123.png"
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
So a partial run is resumable and you don't re-upload the same image twice.
|
|
175
|
-
|
|
176
|
-
### 6. Batch-import items
|
|
177
|
-
|
|
178
|
-
For each file in `src/content/<collection>/`:
|
|
179
|
-
|
|
180
|
-
```js
|
|
181
|
-
import fs from 'node:fs';
|
|
182
|
-
import path from 'node:path';
|
|
183
|
-
import matter from 'gray-matter';
|
|
184
|
-
|
|
185
|
-
const files = fs.readdirSync('src/content/blog').filter(f => /\.mdx?$/.test(f));
|
|
186
|
-
for (const file of files) {
|
|
187
|
-
const raw = fs.readFileSync(`src/content/blog/${file}`, 'utf8');
|
|
188
|
-
const { data, content } = matter(raw);
|
|
189
|
-
const slug = file.replace(/\.mdx?$/, '');
|
|
190
|
-
const body = await md2html(content);
|
|
191
|
-
|
|
192
|
-
// create_collection_item via the MCP
|
|
193
|
-
await mcp.callTool('create_collection_item', {
|
|
194
|
-
collection: 'blog',
|
|
195
|
-
status: data.draft ? 'draft' : 'published',
|
|
196
|
-
fields: {
|
|
197
|
-
title: data.title,
|
|
198
|
-
slug,
|
|
199
|
-
description: data.description,
|
|
200
|
-
date: data.pubDate ? new Date(data.pubDate).toISOString().slice(0, 10) : null,
|
|
201
|
-
updated_date: data.updatedDate ? new Date(data.updatedDate).toISOString().slice(0, 10) : null,
|
|
202
|
-
hero_image: mediaMap[data.heroImage] || data.heroImage,
|
|
203
|
-
author: data.author,
|
|
204
|
-
tags: (data.tags || []).join(', '),
|
|
205
|
-
body,
|
|
206
|
-
},
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
Rate-limit awareness: spawn at most 5 parallel `create_collection_item` calls; the API caps at ~60 writes/minute and responds with 429 + `Retry-After` if exceeded.
|
|
212
|
-
|
|
213
|
-
Set `status: 'draft'` (or honour Astro's `draft: true` frontmatter) for items the user should review before publishing. Only published items get static pages.
|
|
214
|
-
|
|
215
|
-
### 7. Build the listing page
|
|
216
|
-
|
|
217
|
-
```
|
|
218
|
-
create_page title="Blog" slug="blog" status="published" content_mode="html"
|
|
219
|
-
html_content="<section><h1>Blog</h1>
|
|
220
|
-
<!-- typeroll:listing:blog -->
|
|
221
|
-
<!-- /typeroll:listing:blog -->
|
|
222
|
-
</section>"
|
|
223
|
-
|
|
224
|
-
regenerate_collection_listing
|
|
225
|
-
collection="blog"
|
|
226
|
-
page_id="blog"
|
|
227
|
-
item_template="<article class=\"blog-card\"><a href=\"{{url}}\"><h2>{{title}}</h2><p>{{description}}</p><time>{{date}}</time></a></article>"
|
|
228
|
-
wrap_open="<div class=\"blog-grid\">"
|
|
229
|
-
wrap_close="</div>"
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
See `tr-blog` for full styling and post-import update flow.
|
|
233
|
-
|
|
234
|
-
### 8. Translate standalone pages
|
|
235
|
-
|
|
236
|
-
For each non-dynamic `.astro` page under `src/pages/`:
|
|
237
|
-
|
|
238
|
-
```
|
|
239
|
-
read_partial partial_id="header" # learn target's nav style
|
|
240
|
-
# Re-skin the page content using target site's CSS variables and partials.
|
|
241
|
-
create_page title="About" slug="about" status="draft" content_mode="html"
|
|
242
|
-
html_content="..."
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
Default to **draft** — the user reviews each page before publishing.
|
|
246
|
-
|
|
247
|
-
For dynamic Astro pages (`[slug].astro` that consume a collection), you're already done: the matching Typeroll collection's `route_template` produces the same URLs at build time.
|
|
248
|
-
|
|
249
|
-
### 9. Add redirects for URL changes
|
|
250
|
-
|
|
251
|
-
If Astro's slugs differed from what you derived for Typeroll (e.g. Astro had `/posts/my-article` but you want `/blog/my-article`), bulk-add redirects:
|
|
252
|
-
|
|
253
|
-
```
|
|
254
|
-
add_redirect from="/posts/my-article" to="/blog/my-article" status=301
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
Or build a redirect map from the `astro-migration-state.json` and apply it in one pass.
|
|
258
|
-
|
|
259
|
-
### 10. Deploy
|
|
260
|
-
|
|
261
|
-
```
|
|
262
|
-
trigger_deploy
|
|
263
|
-
get_deploy_status job_id=<id>
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
Browse the resulting site, compare against the Astro source, surface anything that drifted.
|
|
267
|
-
|
|
268
|
-
## Astro-specific gotchas
|
|
269
|
-
|
|
270
|
-
- **`.mdx` files with custom components.** Components inside MDX (`<MyCustom prop="..." />`) will not render in Typeroll because the component definitions don't migrate. Two options: (1) replace each component with its rendered HTML output (run the Astro build, scrape the rendered HTML, use that as `body`); (2) if the component is a reusable visual element used across many items, factor it into a Typeroll partial and replace MDX usages with `<x-include name="..." />` calls. See `tr-page-template` for the partial-include pattern.
|
|
271
|
-
- **`src/content/config.ts` typed `image()` helper.** Astro resolves `image()` fields at build time to optimised assets. After migration the Typeroll `hero_image` field carries the original source URL — re-upload via step 5 to get it onto the Typeroll CDN.
|
|
272
|
-
- **`getCollection` filters at runtime.** If `src/pages/blog/index.astro` does `getCollection('blog', ({ data }) => !data.draft)`, Typeroll handles this via `status` on the item. Don't translate the filter — set `status: 'draft'` on items where `data.draft === true`.
|
|
273
|
-
- **Per-tag pages (`/blog/tag/[tag].astro`).** Typeroll doesn't auto-generate these. Either (a) drop tag pages and use a client-side filter in the blog listing JS, (b) generate them by enumerating unique tags and calling `create_page` per tag with a server-side-pre-filtered listing. (a) is preferable for ≤dozens of tags.
|
|
274
|
-
- **`rehype-pretty-code` / shiki / fenced code with syntax highlighting.** The HTML output of these contains inline styles that the Typeroll sanitiser preserves. The colours match the Astro site's theme at import time; redoing the target design later means re-running the highlighter against the same markdown source. Keep a copy of the raw markdown if you might.
|
|
275
|
-
- **`og:image` per page from `astro-og-image` style plugins.** Typeroll has its own SEO surface (`seo_title`, `seo_description`, `seo_og_image`). Set them explicitly on each page during step 8.
|
|
276
|
-
- **i18n via `src/content/<lang>/<collection>/`.** Typeroll's site-level `default_language` + per-page `language` field cover this (capabilities: `supports_language_per_page: true`). Map each language directory to per-item `language: 'sv-SE' | 'en-US' | …` instead of separate collections.
|
|
277
|
-
|
|
278
|
-
## Mixing imported + new content
|
|
279
|
-
|
|
280
|
-
Half-migrate, leave drafts, let the user inspect, iterate. You can:
|
|
281
|
-
|
|
282
|
-
- Import only collections, skip standalone pages, let the user rebuild those from scratch.
|
|
283
|
-
- Import everything as `status: 'draft'`, treat publishing as a per-item human review pass.
|
|
284
|
-
- Mix sources: pull article bodies from Astro markdown, use Claude to generate fresh excerpts/SEO metadata before writing the item.
|
|
285
|
-
|
|
286
|
-
Keep the local `astro-migration-state.json` honest — it's the only way to make a partial run resumable when the API rate-limits or a markdown parser trips on an edge case file.
|
|
287
|
-
|
|
288
|
-
## Storage prerequisite
|
|
289
|
-
|
|
290
|
-
Before reading or importing source content, call `get_import_readiness` (Core
|
|
291
|
-
0.1.95 / MCP 0.44.68 or later). If `ready` is false, stop the import and show the
|
|
292
|
-
returned message and Publishing settings link. The organization must connect
|
|
293
|
-
and verify its own storage first. Do not fall back to draft storage, hotlink
|
|
294
|
-
source images, or use ordinary page-write tools to bypass the import gate.
|
|
295
|
-
Use `upload_media_from_url` for referenced source images; the customer’s
|
|
296
|
-
Cloudflare transfer Worker copies and verifies them directly in R2, independently
|
|
297
|
-
of the GitHub/Cloudflare build-provider choice.
|
|
6
|
+
# Migrate an Astro site
|
|
7
|
+
|
|
8
|
+
Astro Content Collections are source data. In Typeroll, each source record
|
|
9
|
+
becomes a Page, and each source schema becomes a Content type. Static Astro
|
|
10
|
+
pages use that same Page model. Shared Astro layouts become Page templates,
|
|
11
|
+
partials or reusable block types; no separate item storage is created.
|
|
12
|
+
|
|
13
|
+
## Inventory before writing
|
|
14
|
+
|
|
15
|
+
Read the source repository's routing, content loaders, schema, frontmatter,
|
|
16
|
+
layouts, components, styling and public assets. New Astro projects can define
|
|
17
|
+
loaders in `src/content.config.ts`; older projects may use
|
|
18
|
+
`src/content/config.ts` and files under `src/content/`. Follow what the actual
|
|
19
|
+
project uses, including generated route logic and trailing-slash policy.
|
|
20
|
+
|
|
21
|
+
Discover the target with `get_site`, `get_site_capabilities`, `list_pages`,
|
|
22
|
+
`list_content_types`, `list_page_templates` and `list_block_types`. Existing target
|
|
23
|
+
content remains out of scope unless the user authorized replacing it. Create a
|
|
24
|
+
site version for the migration and pass it consistently on all versioned calls.
|
|
25
|
+
Call `get_migration_readiness` before import; connect verified customer storage
|
|
26
|
+
before transferring any source content or media.
|
|
27
|
+
|
|
28
|
+
Record a URL inventory from the existing site and source routing. Use explicit
|
|
29
|
+
Page paths to preserve nested routes or frontmatter-based permalinks. Do not
|
|
30
|
+
assume that a filename alone determines the production URL.
|
|
31
|
+
|
|
32
|
+
## Map the source
|
|
33
|
+
|
|
34
|
+
- Common frontmatter such as title, slug, author, publication date and SEO maps
|
|
35
|
+
to top-level Page metadata.
|
|
36
|
+
- Other schema fields become the Content type's custom fields and Page `fields`.
|
|
37
|
+
Preserve typed objects and arrays; use `page_ref`/`page_ref_list` for relations.
|
|
38
|
+
- Markdown becomes native Page body blocks. First render Markdown to HTML using
|
|
39
|
+
the source project's parser, then review block conversion. MDX components
|
|
40
|
+
require explicit equivalents; never drop them as if they were plain Markdown.
|
|
41
|
+
- A shared layout becomes a reusable Page template with `template_content_slot`.
|
|
42
|
+
Assign it as the type's default. Header/footer and reusable fragments can be
|
|
43
|
+
partials. Use native blocks before choosing a rare reviewed HTML/embed exception.
|
|
44
|
+
- Browser scripts, integrations and server-rendered endpoints need separate
|
|
45
|
+
review. A static Page cannot inherit a private server runtime by copying its
|
|
46
|
+
source text. Configure the supported Forms/Extension runtime explicitly.
|
|
47
|
+
|
|
48
|
+
Create templates with `create_page_template`, types with `create_content_type`,
|
|
49
|
+
then one `create_page` per source record. Use returned Page IDs, not source IDs
|
|
50
|
+
or slugs, for later updates and previews. For linked content, create the Pages
|
|
51
|
+
first and resolve their reference fields in a second pass.
|
|
52
|
+
|
|
53
|
+
Upload assets to connected storage and rewrite source-relative image references
|
|
54
|
+
to returned media URLs. Use direct upload URLs for local bytes and the customer
|
|
55
|
+
transfer flow for remote media; do not relay large base64 payloads through the
|
|
56
|
+
model. Preserve alt text, captions, dimensions, links and image variants.
|
|
57
|
+
|
|
58
|
+
## Listing and verification
|
|
59
|
+
|
|
60
|
+
An archive is a Page with `core/page_list` filtered by `content_type`. Configure
|
|
61
|
+
sorting and pagination from the block schema. It reads saved Pages at build
|
|
62
|
+
time; do not generate a second listing representation or call a regeneration tool.
|
|
63
|
+
|
|
64
|
+
Check representative long/short bodies, code, tables, images, captions, embedded
|
|
65
|
+
components and related links at desktop and mobile widths. Compare the source
|
|
66
|
+
and Typeroll preview, then a fresh authorized static build. Verify every inventory
|
|
67
|
+
URL and redirect, canonical/hreflang, sitemap inclusion, noindex state and assets.
|
|
68
|
+
Save working copies before publication. Keep the source host and DNS in place
|
|
69
|
+
until the candidate passes checks and the user authorizes its cutover.
|
|
@@ -6,7 +6,7 @@ description: Use when migrating SEVERAL sites at once — a WordPress multisite
|
|
|
6
6
|
# Migrate a multisite / multi-domain family to Typeroll
|
|
7
7
|
|
|
8
8
|
> **The buffer model (draft writes).** Every content write in this recipe
|
|
9
|
-
> (pages, blocks
|
|
9
|
+
> (pages, blocks and partials) lands in an unsaved per-doc
|
|
10
10
|
> DRAFT — deploys and plain previews only see SAVED content. For recipe-style
|
|
11
11
|
> build work, pass `save: true` on write calls (the work is pre-approved by
|
|
12
12
|
> the task itself), or run `commit_working_copy` per doc before any
|
package/skills/tr-migrate-wp.md
CHANGED
|
@@ -6,7 +6,7 @@ description: Use when the user asks to migrate a WordPress site to Typeroll, men
|
|
|
6
6
|
# Migrate from WordPress to Typeroll
|
|
7
7
|
|
|
8
8
|
> **The buffer model (draft writes).** Every content write in this recipe
|
|
9
|
-
> (pages, blocks
|
|
9
|
+
> (pages, blocks and partials) lands in an unsaved per-doc
|
|
10
10
|
> DRAFT — deploys and plain previews only see SAVED content. For recipe-style
|
|
11
11
|
> build work, pass `save: true` on write calls (the work is pre-approved by
|
|
12
12
|
> the task itself), or run `commit_working_copy` per doc before any
|
|
@@ -27,7 +27,7 @@ get_migration_readiness source_url="https://oldsite.com"
|
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
When the migration includes reusable page/item layouts, include each proposed
|
|
30
|
-
block composition and its
|
|
30
|
+
block composition and its content type fields in this same call. A
|
|
31
31
|
`waiting_for_native_support` result means leave that template intact and do
|
|
32
32
|
not replace the gap with generic custom blocks, raw HTML, or corrective site
|
|
33
33
|
CSS. Independent content and SEO work may continue. Rerun the review after the
|
package/skills/tr-new-site.md
CHANGED
|
@@ -6,7 +6,7 @@ description: Use when the user wants to create a new Typeroll site from scratch,
|
|
|
6
6
|
# Bootstrap a new Typeroll site
|
|
7
7
|
|
|
8
8
|
> **The buffer model (draft writes).** Every content write in this recipe
|
|
9
|
-
> (pages, blocks
|
|
9
|
+
> (pages, blocks and partials) lands in an unsaved per-doc
|
|
10
10
|
> DRAFT — deploys and plain previews only see SAVED content. For recipe-style
|
|
11
11
|
> build work, pass `save: true` on write calls (the work is pre-approved by
|
|
12
12
|
> the task itself), or run `commit_working_copy` per doc before any
|
|
@@ -55,11 +55,11 @@ Common requirements that are easy to misclassify:
|
|
|
55
55
|
|---|---|
|
|
56
56
|
| Full-bleed hero flush below the header | `core/section` + `core/hero`; block-mode sections already own the full width and have no page-shell padding |
|
|
57
57
|
| Responsive icon/card grid | `core/grid` + `core/icon_box`, or `core/feature_grid`; set responsive fields with `set_block_responsive` |
|
|
58
|
-
| Custom cards backed by
|
|
59
|
-
| Grouped
|
|
58
|
+
| Custom cards backed by Pages | `core/repeater` / `core/page_list` with a site-authored `item_compatible` block type as `item_block` |
|
|
59
|
+
| Grouped Page listing | `core/repeater` with `group_by`; array-valued fields place an item in every matching group |
|
|
60
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
|
|
62
|
-
| Previous/next
|
|
61
|
+
| Generated heading index | `core/table_of_contents`; choose heading levels; links always come from the current Page headings |
|
|
62
|
+
| Previous/next Page links | `template/page_navigation`; defaults to content type sort 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 |
|
|
@@ -199,14 +199,14 @@ truth):
|
|
|
199
199
|
(run `generate_image_variants` after upload) — the in-portal preview
|
|
200
200
|
shows a plain `<img>`, the deployed site gets the upgrade. Use the
|
|
201
201
|
`radius` field for rounded corners.
|
|
202
|
-
- **Repeaters/listings:** `core/
|
|
202
|
+
- **Repeaters/listings:** `core/page_list`, `gallery`,
|
|
203
203
|
`feature_grid` etc. — alias blocks over `core/repeater`. Use these for
|
|
204
|
-
|
|
204
|
+
Pages of a content type instead of hand-writing listing markup. The base
|
|
205
205
|
repeater also supports `group_by`, group ordering/headings, multi-valued
|
|
206
206
|
membership, filters, custom `item_block`, and `item_overrides`.
|
|
207
207
|
- **Long-form navigation:** `core/table_of_contents` builds an anchor list
|
|
208
|
-
from page headings.
|
|
209
|
-
`template/
|
|
208
|
+
from page headings. Page templates use
|
|
209
|
+
`template/page_navigation` for deterministic previous/next links.
|
|
210
210
|
- **Forms:** `create_form`, then place `core/form` with its `form_id`.
|
|
211
211
|
HTML-mode pages use `<x-form id="…" />`; both paths render the same signed
|
|
212
212
|
shell and runtime. See `tr-forms`.
|