@typeroll/mcp-server 0.45.100 → 0.45.102

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.
@@ -79,6 +79,22 @@ Save the response's `id` — pass it as `version=<id>` on every
79
79
  subsequent call. Branches default `robots_blocked: true` so a
80
80
  half-finished redesign won't be indexed.
81
81
 
82
+ ### 2a. Launch basics (ask early)
83
+
84
+ Ask the user for these once, early in the project. Read `read_site_settings` first and ask only for
85
+ what is missing. Each item is optional. Record a skipped item in
86
+ `decisions.md`, so the launch check in the last step holds no surprises.
87
+
88
+ - **Default share image.** Ask the user to choose or create the image that
89
+ social networks and chat apps show when a page has no image of its own:
90
+ upload one (`create_upload_url` or `upload_media_from_url`), pick an existing
91
+ one (`list_media`), or create one with `tr-imagegen`. Use a 1200×630 px PNG or
92
+ JPEG and set it as `default_og_image` with `update_site_settings`. Never
93
+ generate a title card from the page title instead. The user may skip this.
94
+ - **Organization.** The business name, logo and official profile URLs
95
+ (LinkedIn, Instagram, GitHub and similar). Set `organization` with `same_as`;
96
+ it becomes the home page's Organization schema.
97
+
82
98
  ### 2b. Write the design spec (REQUIRED — before you build)
83
99
 
84
100
  Every redesign branch MUST carry a written design spec. Without it the
@@ -249,7 +265,17 @@ link for your own verification:
249
265
  Default: review/iterate on the reused DB-live preview; deploy only for the
250
266
  compiled output, the published-address checks in step 6, or merge. Wait for an explicit "looks good, ship it."
251
267
 
252
- ### 7. Merge + deploy
268
+ ### 7. Launch: merge and deploy (required)
269
+
270
+ A site is not finished until this step has run. Call `read_site_readiness`
271
+ before the production publication and again after it. For every item with the
272
+ status `warning` or `suggestion`, either fix it with the tool its `fix` names,
273
+ or record in `decisions.md` (or the starter's `qa/` folder) why it stays open.
274
+ Tell the user which items remain. A missing default share image is only a
275
+ suggestion; leave it if the user chose to skip it.
276
+
277
+ The report warns and never blocks a publication. A clean report is not approval
278
+ to publish: publish only when the user has approved it.
253
279
 
254
280
  Before asking for sign-off, summarise exactly what will land:
255
281
 
@@ -261,6 +287,7 @@ Then, once approved (creating and merging branches need site admin
261
287
  permission):
262
288
 
263
289
  ```
290
+ read_site_readiness # on the branch, before the merge
264
291
  merge_branch version_id="<branch>" # branch's diffs land on main
265
292
  trigger_deploy
266
293
  get_deploy_status job_id=<id> # poll until succeeded
@@ -275,6 +302,13 @@ delete_branch version_id="<branch>" # tidy up
275
302
  (You can also leave the branch around as a record of the redesign;
276
303
  disk cost is tiny.)
277
304
 
305
+ Run `read_site_readiness` again after the publication. It reads saved content
306
+ and settings, so confirm the rest on the live site: the AI crawler zone check
307
+ needs the site's website host, and a Search Console property verified by DNS
308
+ is not visible to Typeroll. The
309
+ [launch checklist](https://typeroll.com/docs/guides/launch-checklist/)
310
+ explains every item.
311
+
278
312
  ## Pitfalls
279
313
 
280
314
  - **Forgetting `version=` on writes.** Every call you make on the
package/skills/tr-seo.md CHANGED
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  name: tr-seo
3
- description: Use when the user asks to improve SEO, fix meta tags, add structured data, check page titles, or audit the site's search visibility. Triggers on "SEO", "meta descriptions", "Google ranking", "structured data", "JSON-LD", "sitemap", "sökoptimering", or "hjälp mig synas på Google".
3
+ description: Use before a site's first launch and whenever the user asks to improve SEO, fix titles or meta descriptions, set a share image, add structured data, check the sitemap or robots.txt, control AI crawlers, or audit search visibility. Triggers on "launch", "go live", "SEO", "meta descriptions", "share image", "Google ranking", "structured data", "JSON-LD", "sitemap", "llms.txt", "AI crawlers", "sökoptimering", or "hjälp mig synas på Google".
4
4
  ---
5
5
 
6
- # SEO audit and improvements for a Typeroll site
6
+ # SEO and launch basics for a Typeroll site
7
7
 
8
8
  > **The buffer model (draft writes).** Every content write in this recipe
9
9
  > (pages, blocks and partials) lands in an unsaved per-doc
@@ -12,252 +12,276 @@ description: Use when the user asks to improve SEO, fix meta tags, add structure
12
12
  > the task itself), or run `commit_working_copy` per doc before any
13
13
  > `trigger_deploy`. Preview your drafts with `include_working_copy: true`.
14
14
 
15
+ Run this recipe at launch, from the last step of `tr-new-site`, the migration
16
+ recipes and `tr-redesign-branch`, and whenever the user asks about search
17
+ visibility. Start with `read_site_readiness`: it lists what is missing on the
18
+ whole site, with a fix and a guide link per item. Most of what search engines
19
+ and AI agents need, the platform produces on its own; your work is the content
20
+ and the few settings only the owner can decide.
15
21
 
16
22
  ## What Typeroll handles automatically
17
23
 
18
- - `<html lang>` from site `language` setting (per-page override via `language` field)
19
- - `<title>` = `page.seo_title || page.title + settings.default_seo_suffix`
20
- - `<meta name="description">` from `page.seo_description`
21
- - `<meta name="robots">` from `page.noindex`
22
- - `<meta property="og:*">` Open Graph tags from seo_title, seo_description, og_image
23
- - `<link rel="canonical">` from `page.canonical_url` (falls back to the page's own URL)
24
- - Article schema from `kind: "article"` + `author` + `date_published`
25
- - Page schema from `kind: "page"` (default)
26
- - `robots.txt` from `settings.robots_txt`
27
- - Sanitized HTML that preserves semantic structure
24
+ Every publication produces these without any tool call. Do not recreate them
25
+ by hand, and do not add a second copy through `json_ld`, `scripts_head` or a
26
+ page.
27
+
28
+ **Head of every page**
29
+
30
+ - `<html lang>` from the Page `language`, otherwise the site `language`.
31
+ - `<title>`: `seo_title`, otherwise the Page title, plus
32
+ `default_seo_suffix` unless the Page sets `append_seo_suffix: false`.
33
+ - `<meta name="description">`: `seo_description`, then
34
+ `default_meta_description`, then the tagline.
35
+ - `<link rel="canonical">`: the resolved route on the publication's origin, or
36
+ an explicit `canonical_url`.
37
+ - `<meta name="robots">` from `noindex` and `nofollow`, and from the site-wide
38
+ and version restrictions.
39
+ - Open Graph and Twitter card tags (`og:title`, `og:description`, `og:image`,
40
+ `twitter:card`, `twitter:site` from `twitter_handle`). Sharing text uses
41
+ `og_title` and `og_description` when set.
42
+ - Share image chain: `og_image`, then a public Content type field mapped to
43
+ `image`, then `default_og_image`, then the logo. An SVG, AVIF or TIFF share
44
+ image from the site's media library is published as a 1200×630 PNG copy,
45
+ contained on the theme's background colour; the original stays the page
46
+ image. `og:image:type`, `og:image:width` and `og:image:height` are emitted.
47
+ - hreflang `<link rel="alternate">` for Pages with `alternates`.
48
+ - A Markdown rendition of each indexable Page at `<page path>index.md`,
49
+ announced with `<link rel="alternate" type="text/markdown">`.
50
+ - The first content images are never lazy and get `fetchpriority="high"`, and
51
+ a first section's background image is preloaded; later images are lazy.
52
+ Logos and small icons do not count as the first images.
53
+
54
+ **Structured data (JSON-LD)**
55
+
56
+ - `Organization` and `WebSite` on the home page, from `site_name`, `tagline`,
57
+ `organization`, `logo`, contact and social settings.
58
+ - `Article` for Pages with `kind: "article"`, with dates and `author`.
59
+ - `BreadcrumbList` on every page below the home page, from resolved routes.
60
+ - Content type schema from `schema_type` and `schema_field_map`.
61
+ - `FAQPage` from an Accordion block (`core/accordion`) when every item's title
62
+ ends with a question mark (`?`, `?`, `؟`) and has an answer. Nothing is
63
+ added when the Page's `json_ld` or its Content type schema already declares
64
+ `FAQPage`, so it is never emitted twice.
65
+
66
+ **Site files**
67
+
68
+ - `robots.txt`: your `robots_txt` setting, with the sitemap lines added. The
69
+ `ai_crawler_policy` setting adds the matching AI crawler groups.
70
+ A duplicate load of a theme font in custom CSS or `scripts_head` is reported
71
+ by the readiness item `duplicate_fonts`, not removed.
72
+ - `sitemap.xml`: published, indexable Page routes. With more than 45,000
73
+ URLs it becomes a sitemap index over numbered `sitemap-<n>.xml` files.
74
+ Pages with `alternates` carry their hreflang entries.
75
+ - `sitemap-images.xml`: the public images of each indexable Page.
76
+ - `llms.txt`: a Markdown map of the site for AI agents, grouped by Content type
77
+ and language section, with each Page's description and links to the
78
+ sitemap and `llms-full.txt`.
79
+ - `llms-full.txt`: the Markdown of the indexable Pages in one file, with a size
80
+ cap.
81
+ - The `Content-Signal` response header, when `ai_crawler_policy` is not
82
+ `allow_all`.
83
+
84
+ Noindex and unlisted Pages, drafts and blocked versions are left out of every
85
+ site file.
28
86
 
29
87
  ## Recipe
30
88
 
31
- ### 1. Audit current state
89
+ ### 1. Read the site's state
32
90
 
33
91
  ```
34
- list_pages status="all"
92
+ read_site_readiness
35
93
  read_site_settings
94
+ list_pages status="all"
36
95
  ```
37
96
 
38
- For each page, check:
39
- - Does the rendered title accurately identify the page, including any suffix?
40
- - Is the description useful, specific and supported by the page's content?
41
- Search snippets may be rewritten or truncated; fixed character counts are
42
- not acceptance rules and must not cause padding or lost meaning.
43
- - Is `og_image` set for the homepage and key landing pages?
44
- - Does the page have exactly one `<h1>`?
45
-
46
- ### 2. Fix missing meta descriptions
47
-
48
- ```
49
- batch_update_pages updates=[
50
- {page_id: "home", patch: {seo_description: "Acme designar rum..."}},
51
- {page_id: "om-oss", patch: {seo_description: "Vi är ett..."}},
52
- {page_id: "tjanster", patch: {seo_description: "Våra tjänster..."}}
53
- ]
54
- ```
55
-
56
- Guidelines:
57
- - Use the length needed for a clear, accurate summary; avoid padding
58
- - Include the most important keyword naturally
59
- - Make it a compelling reason to click, not a summary of the page's nav
97
+ `read_site_readiness` returns `items` with `id`, `status` (`ok`,
98
+ `suggestion` or `warning`), `message`, `fix` and `guide`. Work through the
99
+ warnings first. It never blocks a publication, and a clean report is not
100
+ approval to publish.
60
101
 
61
- ### 3. Fix page titles
102
+ For each important Page, check:
62
103
 
63
- SEO title = what Google shows in search results.
104
+ - Does the title identify the page, including any suffix?
105
+ - Is the description specific and supported by the page's content? Search
106
+ engines may rewrite or shorten snippets; never pad text to a length.
107
+ - Does the page have exactly one H1?
64
108
 
65
- If `settings.default_seo_suffix` is set (e.g. " — Acme Studio"), every
66
- page whose `seo_title` is empty will show `title + suffix`. That's usually
67
- fine for inner pages; set an explicit `seo_title` only when you want
68
- something different.
109
+ ### 2. Launch basics only the owner can decide
69
110
 
70
- ```
71
- update_site_settings {"default_seo_suffix": " — Acme Studio"}
111
+ Read `read_site_settings` first and ask only for what is missing. Each item is
112
+ optional; record a skipped item in `decisions.md`.
72
113
 
73
- # Set the canonical URL style once per site. Existing sites default to `always`.
74
- update_site_settings {"trailing_slash": "always"}
114
+ - **Default share image.** Ask the user to choose or create the image shown
115
+ when a page has none of its own: upload one (`create_upload_url` or
116
+ `upload_media_from_url`), pick one with `list_media`, or create one with
117
+ `tr-imagegen`. Use 1200×630 px PNG or JPEG. Never generate a title card
118
+ from the page title instead.
75
119
 
76
- # A page that must keep its exact campaign/title text can opt out.
77
- update_page {"page_id": "campaign", "patch": {"append_seo_suffix": false}, "save": true}
120
+ ```
121
+ update_site_settings default_og_image="<cdn_url>" twitter_handle="@acmestudio"
122
+ ```
78
123
 
79
- update_page page_id="home" patch={
80
- "seo_title": "Acme Studio — Inredningsdesign i Stockholm"
81
- }
82
- ```
124
+ - **Organization and profiles.** The business name, logo and official profile
125
+ URLs:
83
126
 
84
- ### 3b. URL and article conventions
127
+ ```
128
+ update_site_settings organization={"name":"Acme Studio","logo":"<cdn_url>","same_as":["https://www.linkedin.com/company/acme"]}
129
+ ```
85
130
 
86
- When creating or moving pages:
131
+ - **Site description and icons.** `default_meta_description` for pages without
132
+ their own description, and `favicon`, `apple_touch_icon` and `icon_192`
133
+ (see `tr-brand`).
134
+ - **AI crawlers.** `ai_crawler_policy` is `allow_all` (the default, which writes
135
+ nothing), `no_training` or `block_all`:
87
136
 
88
- - Slugs are lowercase kebab-case: `our-services`, not `Our_Services`.
89
- - Reflect hierarchy in the address. A team member lives at `/team/jane-doe`
90
- (set `path`, or use a content type whose `route_template` adds the
91
- prefix), not at `/jane-doe`. Breadcrumbs and their BreadcrumbList schema
92
- follow the resolved route.
93
- - Blog posts and news get `kind: "article"` and an `author`: that emits
94
- Article JSON-LD and `og:type=article`. No author means no author in the
95
- rich result.
96
- - Give shared pages, especially articles, their own `og_image`.
137
+ ```
138
+ update_site_settings ai_crawler_policy="no_training"
139
+ ```
97
140
 
98
- ### 4. Add Open Graph images
141
+ `no_training` disallows training-only crawlers such as GPTBot, ClaudeBot,
142
+ Google-Extended, Applebot-Extended and CCBot, and states
143
+ `Content-Signal: search=yes, ai-input=yes, ai-train=no`. It never blocks
144
+ Googlebot, Bingbot or Applebot. On Cloudflare, the zone's own AI bot policy
145
+ is enforced at the edge and wins over `robots.txt`; blocking Training there
146
+ can also block Googlebot, Bingbot and Applebot. The readiness item
147
+ `ai_crawler_zone_conflict` reports a mismatch. Never change the zone's
148
+ settings yourself: tell the owner what to change.
149
+ - **Pages a business needs.** Privacy policy, contact and a 404 page. Set the
150
+ privacy page as `cookie_consent.privacy_policy_url` when the cookie banner is
151
+ on.
99
152
 
100
- Set `og_image` on pages that get shared on social media. If the site has
101
- a branded hero image, upload it:
153
+ ### 3. Titles and descriptions
102
154
 
103
155
  ```
104
- upload_media_from_url url="https://..." alt="Acme Studio — Inredningsdesign"
105
- # → returns cdn_url
156
+ update_site_settings {"default_seo_suffix": " — Acme Studio", "trailing_slash": "always"}
106
157
 
107
158
  batch_update_pages updates=[
108
- {page_id: "home", patch: {og_image: "<cdn_url>"}},
109
- {page_id: "om-oss", patch: {og_image: "<cdn_url>"}}
159
+ {page_id: "home", patch: {seo_title: "Acme Studio — Interior design in Stockholm", seo_description: "Acme designs..."}},
160
+ {page_id: "about", patch: {seo_description: "We are..."}}
110
161
  ]
111
162
  ```
112
163
 
113
- OG image dimensions: 1200×630px ideal. The platform doesn't resize —
114
- use a correctly-sized source image.
115
-
116
- For pages without their own image, set a site-wide fallback and the X/Twitter
117
- handle (admin permission, as in the portal Settings form):
118
-
119
- ```
120
- update_site_settings default_og_image="<cdn_url>" twitter_handle="@acmestudio"
121
- ```
122
-
123
- ### 5. Add structured data (JSON-LD)
124
-
125
- Typeroll auto-generates Article and Page schema, but you can override or
126
- extend with custom JSON-LD per page. Example: LocalBusiness on the homepage.
127
-
128
- The site-wide Organization schema comes from settings — set it once instead of
129
- repeating it on every page (`null` clears it):
130
-
131
- ```
132
- update_site_settings organization={"name":"Acme Studio","logo":"<cdn_url>","same_as":["https://www.linkedin.com/company/acme"]}
133
- ```
134
-
135
- **FAQ, recipe and event pages have tools.** They validate the input, build
136
- the schema.org JSON-LD and merge it into the page's `json_ld` (a node of the
137
- same type is replaced, anything else is kept). Use them instead of
138
- hand-writing JSON-LD, and copy the content from what the page visibly shows:
139
-
140
- ```
141
- add_faq_schema page_id="faq" items=[
142
- {"question": "Do you deliver on weekends?", "answer": "Yes, Saturdays 9–15."}
143
- ]
144
- add_recipe_schema page_id="kanelbullar" name="Kanelbullar"
145
- ingredients=["500 g vetemjöl", "2 tsk kanel"] instructions=["Blanda degen.", "Grädda i 225 °C."]
146
- prep_time="PT1H30M" cook_time="PT10M" recipe_yield="24 bullar" image_url="<cdn_url>"
147
- add_event_schema page_id="sommarkonsert" name="Sommarkonsert"
148
- start_date="2026-06-12T19:00:00+02:00" location_name="Stadshuset"
149
- location_address="Storgatan 1, Sundsvall" offers_price=250 offers_currency="SEK"
150
- ```
164
+ - Give the home page an explicit `seo_title`, so the suffix does not repeat
165
+ the site name.
166
+ - A page that must keep its exact title can set `append_seo_suffix: false`.
167
+ - The readiness report flags duplicate titles and descriptions, missing or
168
+ repeated H1s and descriptions over 160 characters. Fix them in the content;
169
+ they are warnings, not rules to pad or trim text mechanically.
151
170
 
152
- Rules they enforce: FAQ needs at least one question with an answer; a recipe
153
- needs a name, ingredients and steps, durations are ISO 8601 (`PT30M`) and
154
- URLs absolute; an event needs a name and an ISO 8601 `start_date` (include
155
- the UTC offset), `end_date` not before it, and a price needs
156
- `offers_currency`. Read the returned `warnings`: a recipe without an image or
157
- an event without a location is valid but not eligible for Google's rich
158
- results. Like other content writes they land in the draft — `save: true` or
159
- `commit_working_copy` when approved.
171
+ ### 4. URLs and articles
160
172
 
161
- FAQ markup only belongs on a page that visibly presents those questions and
162
- answers; Google penalizes FAQ markup for content the page does not show.
163
-
164
- For other types write `json_ld` yourself:
165
-
166
- ```
167
- update_page page_id="home" patch={
168
- "json_ld": "{\"@context\":\"https://schema.org\",\"@type\":\"LocalBusiness\",\"name\":\"Acme Studio\",\"url\":\"https://acme.se\",\"telephone\":\"+46812345\",\"address\":{\"@type\":\"PostalAddress\",\"streetAddress\":\"Drottninggatan 1\",\"addressLocality\":\"Stockholm\",\"postalCode\":\"111 51\",\"addressCountry\":\"SE\"}}"
169
- }
170
- ```
171
-
172
- **Important:** JSON-LD goes in the `json_ld` field as a JSON *string*
173
- (not a nested object). The renderer injects it inside
174
- `<script type="application/ld+json">`. To keep several nodes on one page,
175
- store them as `{"@context":"https://schema.org","@graph":[…]}` — the
176
- `add_*_schema` tools do this for you. Read the page first: an update
177
- replaces the whole `json_ld` value.
178
-
179
- Common schemas worth adding:
180
- - Homepage: `LocalBusiness` or `Organization`
181
- - About: `AboutPage`
182
- - Contact: `ContactPage`
183
- - Blog articles: auto-generated from `kind:"article"` + `author`
184
- - FAQ, recipe and event pages: the `add_*_schema` tools above
185
- - Products: `Product` with `offers`
186
-
187
- **Instead of the `schema_markup` workflow.** That workflow runs the model with
188
- the Organization's own AI key; on a Site without that access it fails with
189
- `failure_code: "ai_not_enabled"`. Don't retry it. Do the same work here: read
190
- each published page, pick the one type it genuinely represents (or none),
191
- apply the tool or `json_ld` above, and tell the user you did it yourself.
192
-
193
- ### 6. robots.txt
194
-
195
- The default robots.txt allows all crawlers. Update if needed:
196
-
197
- ```
198
- update_site_settings {
199
- "robots_txt": "User-agent: *\nAllow: /\nSitemap: https://acme.se/sitemap.xml"
200
- }
201
- ```
202
-
203
- Typeroll doesn't generate a sitemap automatically in phase 1. If the
204
- customer needs one, create a `/sitemap` page with HTML that lists all
205
- published pages, or write a static `sitemap.xml` as a page with
206
- `slug: "sitemap.xml"` and HTML-encoded XML (not recommended for large sites).
207
-
208
- ### 7. Canonical URLs
209
-
210
- Set `canonical_url` when a page has a duplicate (e.g. the same content
211
- accessible via two slugs after a migration):
212
-
213
- ```
214
- update_page page_id="tjansterna" patch={
215
- "canonical_url": "https://acme.se/tjanster",
216
- "noindex": true
217
- }
218
- ```
219
-
220
- ### 8. Language settings
173
+ - Slugs are lowercase kebab-case: `our-services`, not `Our_Services`.
174
+ - Reflect hierarchy in the address: a team member lives at `/team/jane-doe`
175
+ (set `path`, or use a Content type whose route pattern adds the prefix).
176
+ Breadcrumbs and their schema follow the resolved route.
177
+ - Blog posts and news get `kind: "article"` and an `author`.
178
+ - Give shared pages, especially articles, their own `og_image`.
179
+ - Link every published page from somewhere. The readiness item `orphan_pages`
180
+ lists pages that no internal link reaches; `check_internal_links` finds
181
+ broken saved links.
182
+
183
+ ### 5. Structured data beyond the automatic output
184
+
185
+ Use structured data only for information the page visibly shows.
186
+
187
+ - **FAQ:** an Accordion block whose item titles are questions ending in a
188
+ question mark, each with an answer, produces `FAQPage` automatically. For
189
+ FAQ content in another block, use `add_faq_schema`.
190
+ - **Recipes and events:** `add_recipe_schema` and `add_event_schema` validate
191
+ the input, build the JSON-LD and merge it into the Page's `json_ld`:
192
+
193
+ ```
194
+ add_recipe_schema page_id="kanelbullar" name="Kanelbullar"
195
+ ingredients=["500 g flour", "2 tsp cinnamon"] instructions=["Mix the dough.", "Bake at 225 °C."]
196
+ prep_time="PT1H30M" cook_time="PT10M" recipe_yield="24 buns" image_url="<cdn_url>"
197
+ add_event_schema page_id="summer-concert" name="Summer concert"
198
+ start_date="2026-06-12T19:00:00+02:00" location_name="City Hall"
199
+ location_address="Main Street 1, Sundsvall" offers_price=250 offers_currency="SEK"
200
+ ```
201
+
202
+ Read the returned `warnings`: a recipe without an image or an event without
203
+ a location is valid but not eligible for rich results.
204
+ - **Products, software and directories:** set the Content type's `schema_type`
205
+ (for example `Product` or `SoftwareApplication`) and map its fields with
206
+ `schema_field_map` in `update_content_type`, rather than writing JSON-LD on
207
+ each Page.
208
+ - **Other types:** write `json_ld` yourself as a JSON string. Keep several
209
+ nodes in one `{"@context":"https://schema.org","@graph":[…]}`. An update
210
+ replaces the whole value, so read the Page first.
211
+
212
+ ```
213
+ update_page page_id="home" patch={
214
+ "json_ld": "{\"@context\":\"https://schema.org\",\"@type\":\"LocalBusiness\",\"name\":\"Acme Studio\",\"url\":\"https://acme.se\"}"
215
+ }
216
+ ```
217
+
218
+ The readiness item `structured_data` reports JSON-LD that is missing required
219
+ properties or has invalid dates or URLs.
220
+
221
+ **Instead of the `schema_markup` workflow.** That workflow uses the
222
+ Organization's own AI key; without it, it fails with
223
+ `failure_code: "ai_not_enabled"`. Don't retry it. Read each published page,
224
+ choose the one type it represents (or none), apply the tools above, and tell
225
+ the user you did it yourself.
226
+
227
+ ### 6. robots.txt, indexing and canonicals
228
+
229
+ - `robots_txt` holds custom crawl rules; the sitemap lines are added for you.
230
+ Use `ai_crawler_policy` for AI crawlers instead of hand-written groups.
231
+ - To keep a page out of search but crawlable, set `noindex: true`. Blocking a
232
+ path in `robots.txt` stops crawlers from reading that directive.
233
+ - Set `canonical_url` only when a page deliberately points elsewhere, for
234
+ example a cross-domain duplicate. Don't combine it with `noindex`.
235
+ - `check_site_indexing` reports the robots policy of the actual address,
236
+ including response headers.
237
+
238
+ ### 7. Languages
221
239
 
222
240
  ```
223
241
  update_site_settings {"language": "sv"}
224
- ```
225
-
226
- Per-page override for multilingual content:
227
- ```
228
242
  update_page page_id="about-en" patch={"language": "en"}
229
243
  ```
230
244
 
231
- ### 9. Heading audit
245
+ For several languages on one site, use `language_sections` and Page
246
+ `alternates`; see the multilingual sites guide.
232
247
 
233
- Use `search_pages` to find structural problems:
248
+ ### 8. Search Console
234
249
 
235
- ```
236
- search_pages contains="<h1" # pages that have at least one H1
237
- ```
250
+ Ask the owner to add the site in Google Search Console. A Domain property
251
+ verified with a DNS TXT record covers every address. For a URL-prefix
252
+ property, put Google's verification `<meta>` tag in `scripts_head` (admin
253
+ permission). Then submit `https://<host>/sitemap.xml`. Record the property in
254
+ `brief/seo.md`. After launch, `import_gsc_performance` reads page clicks and
255
+ impressions into the URL inventory.
238
256
 
239
- Then `read_page` on pages that seem to have none or multiple. Fix via
240
- `update_page patch={html_content: "<corrected HTML>"}`.
257
+ ### 9. Publish and check
241
258
 
242
- ### 10. Deploy
259
+ With the user's approval:
243
260
 
244
261
  ```
262
+ read_site_readiness
245
263
  trigger_deploy
246
264
  get_deploy_status job_id=<id>
265
+ read_site_readiness
247
266
  ```
248
267
 
268
+ Run the report again after the publication. It reads saved content and
269
+ settings: the AI crawler zone check needs the site's website host, and a Search
270
+ Console property verified by DNS is not visible to Typeroll, so confirm it in
271
+ Search Console. Fix or record every open item, and save the result under the
272
+ starter's `qa/` folder. In the portal, the site's overview page has the same
273
+ report under **Launch readiness → Check readiness**. It runs on request, not
274
+ after every publication.
275
+
249
276
  ## Pitfalls
250
277
 
251
- - **Don't stuff keywords.** Write descriptions for humans. Google ignores
252
- `<meta name="keywords">` (not a field in Typeroll anyway).
253
- - **JSON-LD is a string, not a nested field.** Pass the entire schema as
254
- a JSON-encoded string in `json_ld`. The server escapes `</script` before
255
- injection.
256
- - **OG images need absolute URLs.** The `cdn.typeroll.com` URLs are always
257
- absolute — use those.
258
- - **`canonical_url` + `noindex` together.** If you noindex a page AND set
259
- canonical, the canonical is redundant (noindexed pages don't pass equity).
260
- Use one or the other.
261
- - **Default suffix on homepage looks odd.** "Acme Studio — Acme Studio"
262
- happens when title="Acme Studio" and suffix=" — Acme Studio". Set an
263
- explicit `seo_title` for the homepage.
278
+ - **Don't stuff keywords.** Write descriptions for people. Google ignores
279
+ `<meta name="keywords">`, and Typeroll has no such field.
280
+ - **JSON-LD is a string.** Pass the whole schema as a JSON-encoded string in
281
+ `json_ld`. The server escapes `</script` before output.
282
+ - **Share images need absolute URLs.** Media library `cdn_url` values are
283
+ absolute.
284
+ - **FAQ markup must match visible content.** Search engines penalize FAQ
285
+ markup for questions the page does not show.
286
+ - **A site file you write by hand loses.** Don't create Pages named
287
+ `sitemap.xml`, `robots.txt` or `llms.txt`; the publication writes them.
@@ -41,6 +41,19 @@ Verify a primary/surface change in a test Version across header, footer, cards,
41
41
  menus and buttons, then restore the test settings. Do not republish automatically.
42
42
 
43
43
 
44
+ ## Express the brand through settings, not CSS
45
+
46
+ Brand colours belong in `colors`, font families in `fonts`, sizes and spacing
47
+ in the design scales, and recurring looks in named Styles. Editors can see and
48
+ change all of these, and every page follows them. Use `custom_css` only for an
49
+ exception recorded in `decisions.md`, and never to load a font a second time,
50
+ restyle all headings or buttons, or set a hero background image. Run
51
+ `lint_design_tokens` and check the readiness items `duplicate_fonts` and
52
+ `custom_css_overrides` in `read_site_readiness` before launch.
53
+
54
+ The CSS variables below are for those recorded exceptions, HTML-mode pages and
55
+ template markup.
56
+
44
57
  A reference for the *default* design that ships with new Typeroll sites.
45
58
  The customer may have replaced it — always inspect the actual header partial
46
59
  (`read_partial partial_id="header"`) and an existing page before assuming any
@@ -28,6 +28,22 @@
28
28
  - Check publishing readiness and migration launch report. Passing technical
29
29
  validation does not prove visual/editorial completeness or grant launch approval.
30
30
 
31
+ ## Launch
32
+
33
+ Run this before the first production publication, again after it, and after
34
+ major changes. The report covers the whole site; it warns and never blocks.
35
+
36
+ - [ ] Run `read_site_readiness` on the confirmed Site and Version.
37
+ - [ ] Fix each `warning` and `suggestion` with the tool its `fix` names, or
38
+ record in decisions.md why it stays open. A missing default share image is a
39
+ suggestion; leave it when the owner chose to skip it.
40
+ - [ ] Save the result as qa/launch-readiness.md: date, Site, Version, deployed
41
+ revision, each open item with its decision, and the next review date.
42
+ - [ ] After publication, run it again. It reads saved content and settings, so
43
+ confirm in Search Console itself that the property is verified and the
44
+ sitemap is submitted, and record the date in brief/seo.md.
45
+ - [ ] Keep `get_migration_launch_report` as the separate gate for migrations.
46
+
31
47
  Commands/dependencies/limits: scripts/README.md. Design: workflows/design.md.
32
48
  Follow existing owner authorization; test publication, traffic cutover and
33
49
  indexing have distinct effects but do not require repeated approval if covered.
@@ -45,15 +45,24 @@ conversation, not a portal wizard or a new API workflow.
45
45
  alone must not change the motif. Save design_intent and asset exceptions in
46
46
  brief/migration.md, and the direction in brief/brand.md. A fresh design never
47
47
  grants permission to rewrite preserved text.
48
- 5. **Content and behavior** — Page types, shared templates, navigation, forms,
49
- downloads, integrations and who will edit them. Identify missing capabilities
50
- before scaling up. Save to brief/content-model.md. New websites skip migration
51
- preservation choices and establish their brand/content brief here.
48
+ 5. **Content and behavior** — Which pages does the business need? Offer the
49
+ usual set as choices: home, about, services or products, pricing, contact,
50
+ privacy policy and other legal pages, comparisons with alternatives, and
51
+ articles. Then page types, shared templates, navigation, forms, downloads,
52
+ integrations and who will edit them. Write the page plan (title, path,
53
+ purpose, search intent, status) in brief/content-model.md before any design
54
+ work starts. Identify missing capabilities before scaling up. New websites
55
+ skip migration preservation choices and establish their brand/content brief here.
52
56
  6. **SEO and continuity** — Markets, search intent, useful topics and existing
53
57
  valuable URLs. Record evidence separately from hypotheses in brief/seo.md.
54
58
  Confirm metadata policy; text preservation cannot be bypassed as "SEO cleanup".
55
59
  Every old public URL must remain or redirect meaningfully regardless of the
56
60
  two migration choices. Retiring a URL requires a separate agreed exception.
61
+ Ask for the launch basics, each optional: a default share image (choose an
62
+ existing one, upload one or create one with tr-imagegen; never a generated
63
+ title card), the organization's name, logo and official profile URLs, and
64
+ who can verify the site in Google Search Console. Save them under
65
+ "Launch basics" in brief/seo.md, including any the owner skips.
57
66
  7. **Owner rules and review** — Non-negotiable copy/design constraints, editing
58
67
  roles and who approves prototypes, publication, DNS or messages. Save confirmed
59
68
  rules to brief/rules.md. Keep technical access separate from user authorization.