@respira/wordpress-mcp-server 7.2.18 → 7.4.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.
Files changed (88) hide show
  1. package/dist/acf-tools.d.ts +0 -10
  2. package/dist/acf-tools.d.ts.map +1 -1
  3. package/dist/acf-tools.js +0 -15
  4. package/dist/acf-tools.js.map +1 -1
  5. package/dist/config.d.ts.map +1 -1
  6. package/dist/config.js +31 -36
  7. package/dist/config.js.map +1 -1
  8. package/dist/server.d.ts +0 -47
  9. package/dist/server.d.ts.map +1 -1
  10. package/dist/server.js +1155 -605
  11. package/dist/server.js.map +1 -1
  12. package/dist/wordpress-client.d.ts +61 -29
  13. package/dist/wordpress-client.d.ts.map +1 -1
  14. package/dist/wordpress-client.js +271 -148
  15. package/dist/wordpress-client.js.map +1 -1
  16. package/package.json +2 -2
  17. package/skills/activity-report-composer/README.md +38 -0
  18. package/skills/activity-report-composer/SKILL.md +167 -0
  19. package/skills/activity-report-composer/metadata.json +42 -0
  20. package/skills/brand-voice-synthesizer/README.md +43 -0
  21. package/skills/brand-voice-synthesizer/SKILL.md +259 -0
  22. package/skills/brand-voice-synthesizer/metadata.json +46 -0
  23. package/skills/build-oxygen6-page/SKILL.md +59 -0
  24. package/skills/conversion-audit/README.md +37 -0
  25. package/skills/conversion-audit/SKILL.md +185 -0
  26. package/skills/conversion-audit/metadata.json +46 -0
  27. package/skills/custom-post-type-architect/README.md +34 -0
  28. package/skills/custom-post-type-architect/SKILL.md +158 -0
  29. package/skills/custom-post-type-architect/metadata.json +39 -0
  30. package/skills/design-system-synthesizer/README.md +46 -0
  31. package/skills/design-system-synthesizer/SKILL.md +395 -0
  32. package/skills/design-system-synthesizer/metadata.json +57 -0
  33. package/skills/figma-to-elementor/SKILL.md +204 -0
  34. package/skills/html-to-bricks/README.md +43 -0
  35. package/skills/html-to-bricks/SKILL.md +135 -0
  36. package/skills/html-to-bricks/metadata.json +41 -0
  37. package/skills/internal-link-builder/SKILL.md +258 -0
  38. package/skills/internal-link-builder/metadata.json +46 -0
  39. package/skills/migrate-beaver-builder-to-bricks/SKILL.md +251 -0
  40. package/skills/migrate-beaver-builder-to-gutenberg/SKILL.md +248 -0
  41. package/skills/migrate-brizy-to-gutenberg/SKILL.md +248 -0
  42. package/skills/migrate-divi-to-breakdance/SKILL.md +312 -0
  43. package/skills/migrate-divi-to-bricks/SKILL.md +321 -0
  44. package/skills/migrate-divi-to-gutenberg/SKILL.md +328 -0
  45. package/skills/migrate-elementor-to-breakdance/SKILL.md +287 -0
  46. package/skills/migrate-elementor-to-bricks/SKILL.md +289 -0
  47. package/skills/migrate-elementor-to-gutenberg/SKILL.md +327 -0
  48. package/skills/migrate-elementor-to-oxygen/SKILL.md +300 -0
  49. package/skills/migrate-oxygen-to-breakdance/SKILL.md +235 -0
  50. package/skills/migrate-oxygen-to-bricks/SKILL.md +237 -0
  51. package/skills/migrate-thrive-architect-to-gutenberg/SKILL.md +257 -0
  52. package/skills/migrate-visual-composer-to-gutenberg/SKILL.md +261 -0
  53. package/skills/migrate-wpbakery-to-bricks/SKILL.md +336 -0
  54. package/skills/migrate-wpbakery-to-gutenberg/SKILL.md +345 -0
  55. package/skills/mobile-experience-report/SKILL.md +719 -0
  56. package/skills/mobile-experience-report/telemetry.ts +137 -0
  57. package/skills/page-template-library/README.md +41 -0
  58. package/skills/page-template-library/SKILL.md +175 -0
  59. package/skills/page-template-library/metadata.json +44 -0
  60. package/skills/prime-the-agent/README.md +49 -0
  61. package/skills/prime-the-agent/SKILL.md +225 -0
  62. package/skills/prime-the-agent/metadata.json +46 -0
  63. package/skills/respira-setup-assistant/SKILL.md +386 -0
  64. package/skills/respira-setup-assistant/metadata.json +36 -0
  65. package/skills/seo-aeo-amplifier/README.md +61 -0
  66. package/skills/seo-aeo-amplifier/SKILL.md +277 -0
  67. package/skills/seo-aeo-amplifier/metadata.json +62 -0
  68. package/skills/stale-content-detector/README.md +41 -0
  69. package/skills/stale-content-detector/SKILL.md +156 -0
  70. package/skills/stale-content-detector/metadata.json +43 -0
  71. package/skills/technical-debt-audit/SKILL.md +691 -0
  72. package/skills/technical-debt-audit/telemetry.ts +142 -0
  73. package/skills/woocommerce-health-check/SKILL.md +719 -0
  74. package/skills/woocommerce-health-check/telemetry.ts +137 -0
  75. package/skills/wordpress-ai-image-optimizer/README.md +49 -0
  76. package/skills/wordpress-ai-image-optimizer/SKILL.md +232 -0
  77. package/skills/wordpress-ai-image-optimizer/metadata.json +63 -0
  78. package/skills/wordpress-site-dna/README.md +81 -0
  79. package/skills/wordpress-site-dna/SKILL.md +669 -0
  80. package/skills/wordpress-site-dna/telemetry.ts +137 -0
  81. package/dist/__tests__/acf-tool-routing.test.d.ts +0 -2
  82. package/dist/__tests__/acf-tool-routing.test.d.ts.map +0 -1
  83. package/dist/__tests__/acf-tool-routing.test.js +0 -37
  84. package/dist/__tests__/acf-tool-routing.test.js.map +0 -1
  85. package/dist/__tests__/cowork-bootstrap.test.d.ts +0 -2
  86. package/dist/__tests__/cowork-bootstrap.test.d.ts.map +0 -1
  87. package/dist/__tests__/cowork-bootstrap.test.js +0 -61
  88. package/dist/__tests__/cowork-bootstrap.test.js.map +0 -1
@@ -0,0 +1,38 @@
1
+ # Activity Report Composer
2
+
3
+ > Turn the audit log of work done on a WordPress site into a polished written report — in six different framings.
4
+
5
+ Respira tracks every edit, snapshot, and rollback on every connected site. This skill turns that log into a written report you can send to a client, publish as a case study, drop into your build-in-public feed, or file for your own records.
6
+
7
+ ## What it does
8
+
9
+ Calls `respira_generate_activity_report` (new in v7.1) to pull the structured data — hours saved, edits made, top tools used, cost saved at agency rate, highlights — then walks the agent through writing the report in your chosen framing.
10
+
11
+ ## The six framings
12
+
13
+ 1. **Agency client report** — formal, addressed to the client, leads with the savings number
14
+ 2. **Case study** — third-person narrative, anonymize toggle available
15
+ 3. **Internal recap** — terse bullets for team standups
16
+ 4. **Testimonial draft** — first-person quote in the operator's voice
17
+ 5. **Build in public** — punchy, social-shaped, what shipped this week
18
+ 6. **Personal recap** — log entry for your own records
19
+
20
+ ## Output formats
21
+
22
+ - Markdown (for Notion, Linear, docs, email)
23
+ - Email-ready HTML
24
+ - Social-shaped (LinkedIn / X post length)
25
+
26
+ ## Triggers
27
+
28
+ - *"generate a client report"*
29
+ - *"make a monthly report"*
30
+ - *"build a case study from this site"*
31
+ - *"what did I ship this month"*
32
+ - *"build-in-public summary"*
33
+
34
+ ## Requires
35
+
36
+ - Respira for WordPress plugin **7.1+** (the underlying MCP tool is new in 7.1)
37
+ - MCP server connected
38
+ - Audit log enabled (default ON)
@@ -0,0 +1,167 @@
1
+ # Activity Report Composer
2
+
3
+ **Version:** 1.0.0
4
+ **Updated:** 2026-05-24
5
+ **Category:** reporting
6
+ **Status:** stable
7
+ **Requires:** Respira for WordPress plugin 7.1+ + MCP server
8
+
9
+ ---
10
+
11
+ ## Description
12
+
13
+ Turn the audit log of work done on a WordPress site into a polished, written report. This skill wraps the new v7.1 `respira_generate_activity_report` MCP tool, which returns structured data (totals, top tools used, hours saved, cost saved at agency rate, highlights). The skill then walks the agent through writing that data into one of six framings.
14
+
15
+ The six framings:
16
+
17
+ 1. **Agency client report** — formal, results-focused, addressed to the client
18
+ 2. **Case study** — third-person narrative for marketing, anonymize-toggle available
19
+ 3. **Internal recap** — for team standups, terse, what shipped + what's next
20
+ 4. **Testimonial draft** — first-person, optimized as a customer quote
21
+ 5. **Build in public** — public-facing, social-media-shaped, what got done this week
22
+ 6. **Personal recap** — for the operator's own records, no marketing varnish
23
+
24
+ ---
25
+
26
+ ## When to Use
27
+
28
+ - End of month — generate a client report for billing
29
+ - Quarterly review — build-in-public summary for socials
30
+ - Pitching a case study to a prospect
31
+ - Capturing testimonial language while the work is fresh
32
+ - Internal weekly review for an agency team
33
+
34
+ ---
35
+
36
+ ## Trigger Phrases
37
+
38
+ - "generate a client report"
39
+ - "make a monthly report"
40
+ - "activity report"
41
+ - "compose an activity report"
42
+ - "build an agency client report"
43
+ - "draft a case study from this site"
44
+ - "build-in-public summary"
45
+ - "internal recap"
46
+ - "what did i ship this month"
47
+ - "client billing report"
48
+
49
+ ---
50
+
51
+ ## Execution Workflow
52
+
53
+ ### Step 1 — Confirm site + window
54
+
55
+ Call `respira_get_active_site`. Ask the user which window to summarize: default is the last 30 days. Common windows: 7 days (weekly), 30 days (monthly), 90 days (quarterly).
56
+
57
+ ### Step 2 — Confirm framing
58
+
59
+ Ask the user which of the six framings to use. If they don't say, recommend based on the trigger phrase ("client report" → agency client report; "build in public" → build in public framing). Default if unspecified: agency client report.
60
+
61
+ ### Step 3 — Pull the structured data
62
+
63
+ Call `respira_generate_activity_report` with the window and framing. The tool returns:
64
+
65
+ ```json
66
+ {
67
+ "client": "string",
68
+ "window": "30 days",
69
+ "framing": "agency_client_report",
70
+ "hoursSaved": "5.1",
71
+ "costSaved": {"amount": "408", "currency": "EUR"},
72
+ "totals": {"edits": 42, "pages": 14, "snapshots": 27, "rollbacks": 2},
73
+ "topTools": [
74
+ {"name": "respira_update_module", "scope": "write", "n": 14},
75
+ {"name": "respira_extract_builder_content", "scope": "read", "n": 23}
76
+ ],
77
+ "notes": ["Migrated 14 blog posts to /journal/...", "..."]
78
+ }
79
+ ```
80
+
81
+ ### Step 4 — Compose the report in the chosen framing
82
+
83
+ Write the report using the framing's voice:
84
+
85
+ **Agency client report** — addressed to the client by name, leads with the headline number (hours saved, cost saved), then the work summary, then next steps. Professional, no informalities.
86
+
87
+ **Case study** — third-person narrative. "Acme Inc. reduced their content production time by 40% in 30 days using Respira-augmented AI workflows." Anonymize toggle: if enabled, replace the client name with "a B2B SaaS company" or similar. Anonymize all identifying details in the highlights.
88
+
89
+ **Internal recap** — bullets, no narrative. "42 edits, 14 pages touched, 0 rollbacks. Top time-saver: bulk Divi module updates. Next: ship the pricing page redesign."
90
+
91
+ **Testimonial draft** — first-person, in the operator's voice, framed as a quote. "In the last 30 days I saved 5 hours of agency time on [client] thanks to Respira's snapshot-first edits. We shipped 14 pages with zero rollbacks."
92
+
93
+ **Build in public** — punchy, social-shaped. "This week on Respira: 42 edits across 14 client pages, 5 hours saved, 0 rollbacks. The agent took a swing, snapshotted before every change, and not once did I have to undo it. Here's what landed →"
94
+
95
+ **Personal recap** — terse log entry for the operator's own notes. Date, totals, what got done, what was hard, what's next. No marketing voice.
96
+
97
+ ### Step 5 — Offer three output formats
98
+
99
+ After the report is composed, ask the user which output they want:
100
+
101
+ - **Markdown** — for pasting into a doc, Notion, Linear, email
102
+ - **Email-ready HTML** — for sending directly through the agency's mail client
103
+ - **Social-shaped** — short version for LinkedIn or X (build-in-public + testimonial framings only)
104
+
105
+ ### Step 6 — Save (optional)
106
+
107
+ Offer to save the report as a custom post type entry on the site (so it shows up in the Activity reports archive). Use `respira_create_custom_post` with `post_type=respira_activity_report` if that CPT exists.
108
+
109
+ ---
110
+
111
+ ## Output template — Agency client report (example)
112
+
113
+ ```markdown
114
+ # Activity Report: {client_name} — {window}
115
+
116
+ **{hoursSaved}h of work saved · €{costSaved} at our standard rate**
117
+
118
+ ## Summary
119
+
120
+ In the last {window}, {totals.edits} edits landed across {totals.pages} pages on {client_name}'s site. {totals.snapshots} snapshots were captured before any change, and {totals.rollbacks} were rolled back during review.
121
+
122
+ ## What we did
123
+
124
+ {notes formatted as bullet list}
125
+
126
+ ## Top operations
127
+
128
+ {topTools formatted as a small table — name, read/write, count}
129
+
130
+ ## Next steps
131
+
132
+ {agent fills in — could be empty if no obvious next steps, or could reference open work}
133
+
134
+ ---
135
+
136
+ Prepared by Respira for {client_name} · {date}
137
+ ```
138
+
139
+ ---
140
+
141
+ ## Anonymization rules (case-study framing only)
142
+
143
+ If the user selects case-study framing with anonymize ON:
144
+
145
+ - Replace client name everywhere with industry descriptor ("a B2B SaaS company", "a Lisbon-based design agency", "a multi-location restaurant group")
146
+ - Replace specific URLs with `[client website]`
147
+ - Replace named pages with generic descriptors ("the pricing page", "the careers section", "a long-form sales landing page")
148
+ - Replace named team members with role descriptors ("their head of marketing", "the founder")
149
+ - Keep all numbers exact — they are the proof
150
+ - Note "Customer data anonymized at customer's request" at the bottom
151
+
152
+ ---
153
+
154
+ ## Hard rules
155
+
156
+ - Never invent numbers. Every figure in the report comes from the `respira_generate_activity_report` response or from the totals counted in the audit log. If the data is empty, say so — do not pad.
157
+ - Never name customers in the build-in-public or social outputs unless the user explicitly OKs it for *this specific report*. Default to "a client" or "an agency I work with."
158
+ - The hours-saved + cost-saved numbers in the structured data already factor in the operator's stated rate. Do not multiply or convert them.
159
+ - Reports are an output, not a record. They live in the user's Markdown / email / dashboard, not in the audit log itself.
160
+
161
+ ---
162
+
163
+ ## Telemetry
164
+
165
+ Records: site URL hash, framing chosen, window length, totals from the response, output format selected, success/failure. No report text, no client name, no notes are sent.
166
+
167
+ Endpoint: `POST https://www.respira.press/api/skills/track-usage`
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "Activity Report Composer",
3
+ "slug": "activity-report-composer",
4
+ "icon": "📊",
5
+ "category": "reporting",
6
+ "description": "Turn the audit log of work done on a WordPress site into a polished written report. Wraps the v7.1 respira_generate_activity_report MCP tool with six framings: agency client report, case study, internal recap, testimonial draft, build-in-public, personal recap.",
7
+ "author": "Respira Team",
8
+ "author_url": "https://respira.press",
9
+ "trigger": "generate a client report",
10
+ "requires_respira": true,
11
+ "requires_woocommerce_addon": false,
12
+ "requires_accessibility_addon": false,
13
+ "is_read_only": true,
14
+ "is_duplicate_first": false,
15
+ "version": "1.0.0",
16
+ "last_updated": "2026-05-24",
17
+ "tools_used": [
18
+ "respira_get_active_site",
19
+ "respira_generate_activity_report",
20
+ "respira_create_custom_post"
21
+ ],
22
+ "detects": [
23
+ "audit_log_window",
24
+ "totals_edits",
25
+ "totals_pages",
26
+ "totals_snapshots",
27
+ "totals_rollbacks",
28
+ "top_tools_used",
29
+ "hours_saved",
30
+ "cost_saved"
31
+ ],
32
+ "generates": [
33
+ "agency_client_report",
34
+ "case_study_markdown",
35
+ "internal_recap",
36
+ "testimonial_draft",
37
+ "build_in_public_post",
38
+ "personal_recap",
39
+ "email_ready_html",
40
+ "social_shaped_summary"
41
+ ]
42
+ }
@@ -0,0 +1,43 @@
1
+ # Brand Voice Synthesizer
2
+
3
+ > Every blog post Claude writes, in your voice — not generic AI voice.
4
+
5
+ Reads 5–10 of your published posts and extracts your brand voice: tone, sentence length, lexicon you reach for, phrases you signature, words you never use. Persists the voice to your site so every future content-writing skill matches it.
6
+
7
+ ## What it captures
8
+
9
+ - **Person:** "we" / "I" / "you" / mixed
10
+ - **Formality:** casual → approachable_professional → formal → academic
11
+ - **Sentence length:** avg + median + p90
12
+ - **Reading grade:** Flesch-Kincaid
13
+ - **Tone descriptors:** 3–5 adjectives (confident, direct, lightly playful, evidence-driven, ...)
14
+ - **Signature phrases:** the multi-word phrases you use repeatedly
15
+ - **Preferred lexicon:** words you reach for ("ship", "wire", "land")
16
+ - **Avoided lexicon:** words your site conspicuously never uses ("leverage", "synergy", "best-in-class")
17
+ - **Punctuation patterns:** em dashes, exclamation marks, oxford comma
18
+ - **Structural patterns:** opens with a question, ends with a CTA, uses bullet lists
19
+
20
+ Plus a paragraph from your own corpus as a "this is your voice" example, and a constructed counter-example showing what your voice is NOT.
21
+
22
+ ## How it's used
23
+
24
+ Once captured, the voice is persisted at the site level. Every Respira content-writing skill from that point on reads the voice before writing — pronouns match, sentence length matches, avoided words stay out.
25
+
26
+ The **avoided lexicon** is the strongest signal. The agent will refuse to write "revolutionary" or "best-in-class" if your voice says you never use those words — even if a prompt asks for them.
27
+
28
+ ## Triggers
29
+
30
+ - *"extract my brand voice"*
31
+ - *"what's my writing style"*
32
+ - *"analyze my tone"*
33
+ - *"build a voice guide"*
34
+
35
+ ## Pairs with
36
+
37
+ [Design System Synthesizer](https://respira.press/skills/design-system-synthesizer) — together they form your complete brand foundation. Visual + verbal.
38
+
39
+ ## Requires
40
+
41
+ - Respira for WordPress plugin **7.1+**
42
+ - MCP server connected
43
+ - At least 3 published posts to sample (5+ for a confident analysis)
@@ -0,0 +1,259 @@
1
+ # Brand Voice Synthesizer
2
+
3
+ **Version:** 1.1.0
4
+ **Updated:** 2026-06-30
5
+ **Freshly updated:** v1.1.0 wires the voice profile into the rest of the brand system. The extracted profile now persists to per-site memory via `respira_get_option` (diff first) + `respira_update_option`, cross-links explicitly with the Page Template Library and Design System Synthesizer skills so copy and layout share one brand foundation, and adds a brand-consistency report built from `respira_generate_activity_report` so you can see how on-voice recent content actually is.
6
+ **Category:** intelligence
7
+ **Status:** stable
8
+ **Requires:** Respira for WordPress plugin 7.1+ + MCP server
9
+
10
+ ---
11
+
12
+ ## Description
13
+
14
+ Read 5–10 published posts on a WordPress site and extract the **brand voice** — tone, lexicon, sentence patterns, person used, formality, signature phrases, phrases the site never uses. Persist it to the site so every future content-writing skill produces copy that sounds like the brand, not like generic AI.
15
+
16
+ This is the verbal counterpart to the [Design System Synthesizer](https://respira.press/skills/design-system-synthesizer). The two together form a complete brand foundation that every future content-generation skill references.
17
+
18
+ ---
19
+
20
+ ## What it produces
21
+
22
+ A structured `brand_voice` artifact stored at the site level. Schema:
23
+
24
+ ```json
25
+ {
26
+ "version": "1.1.0",
27
+ "synthesized_at": "2026-05-24T14:30:00Z",
28
+ "synthesized_from": ["/blog/post-a/", "/blog/post-b/", "..."],
29
+ "n_samples": 8,
30
+ "total_words_sampled": 12450,
31
+ "person": "we",
32
+ "formality": "approachable_professional",
33
+ "sentence_length_avg_words": 14,
34
+ "sentence_length_median_words": 12,
35
+ "sentence_length_p90_words": 28,
36
+ "paragraph_length_avg_sentences": 3.2,
37
+ "reading_grade_avg": 8.4,
38
+ "tone_descriptors": ["confident", "direct", "lightly playful", "evidence-driven"],
39
+ "signature_phrases": [
40
+ "the short version is",
41
+ "here's what we learned",
42
+ "let's break that down"
43
+ ],
44
+ "common_openers": ["here's", "the", "we"],
45
+ "common_closers": ["that's the lesson", "more soon", "questions welcome"],
46
+ "lexicon_preferred": ["ship", "wire", "land", "tighten", "lean into"],
47
+ "lexicon_avoided": ["leverage", "synergy", "best-in-class", "world-class", "innovative", "cutting-edge", "revolutionary"],
48
+ "punctuation_patterns": {
49
+ "em_dash_usage": "frequent",
50
+ "exclamation_marks": "never",
51
+ "oxford_comma": true,
52
+ "ellipsis_usage": "rare",
53
+ "parenthetical_asides": "frequent"
54
+ },
55
+ "structural_patterns": {
56
+ "opens_with_question": "sometimes",
57
+ "uses_headings": "every_post",
58
+ "uses_bullet_lists": "often",
59
+ "uses_code_blocks": "for_technical_posts",
60
+ "uses_blockquotes": "rare",
61
+ "ends_with_call_to_action": "never"
62
+ },
63
+ "examples": {
64
+ "good_paragraph": "We shipped the redesign last week. The short version is: fewer pages, more density, one CTA per screen. Conversion is up 18% on the new pricing page so far. We'll know more by end of month.",
65
+ "bad_paragraph": "We are thrilled to announce the launch of our revolutionary new design! This best-in-class experience leverages cutting-edge UX innovations to deliver unparalleled value!"
66
+ }
67
+ }
68
+ ```
69
+
70
+ The artifact is stored via `respira_update_option('respira_brand_voice', ...)` for v7.1. Same migration path to `respira_intelligence_artifacts` in v7.2 as the design system.
71
+
72
+ ---
73
+
74
+ ## When to Use
75
+
76
+ - First time setting up an AI workflow for a content-heavy site
77
+ - Before running any content-generation skill that produces written copy
78
+ - After a brand voice update (new style guide, new chief content officer, rebrand)
79
+ - Quarterly refresh — voice drifts; resynthesize to catch it
80
+
81
+ ---
82
+
83
+ ## Trigger Phrases
84
+
85
+ - "extract my brand voice"
86
+ - "what's my writing style"
87
+ - "analyze my tone"
88
+ - "build a voice guide"
89
+ - "synthesize my voice"
90
+ - "capture my writing style"
91
+ - "what's the voice of this site"
92
+
93
+ ---
94
+
95
+ ## Execution Workflow
96
+
97
+ ### Step 1 — Confirm site
98
+
99
+ Call `respira_get_active_site` + `respira_get_site_context`.
100
+
101
+ ### Step 2 — Pick representative posts
102
+
103
+ Call `respira_list_posts` with status=publish, limit=20. From the list, pick 5–10 posts that should represent the voice:
104
+
105
+ - Prefer recent posts (last 6 months) over older ones — voice drifts
106
+ - Prefer the site owner's posts over guest posts (look at `author`)
107
+ - Mix lengths: include short posts and long-form
108
+ - Skip auto-generated content (release notes if they're templated, automated changelogs)
109
+ - Skip translated content (the translator's voice contaminates the analysis)
110
+
111
+ If fewer than 5 posts exist, use whatever's there but note `n_samples` honestly.
112
+
113
+ ### Step 3 — Extract each post's content
114
+
115
+ For each picked post, call `respira_read_post(post_id)` or `respira_extract_builder_content(post_id)` depending on the active builder. Strip:
116
+
117
+ - Code blocks (keep the descriptor but exclude the code from voice analysis)
118
+ - Embed shortcodes
119
+ - Image captions (usually different voice from body)
120
+ - Auto-generated footers (linkbacks, "subscribe" CTAs, etc.)
121
+
122
+ ### Step 4 — Analyze
123
+
124
+ For the corpus of cleaned text, compute:
125
+
126
+ 1. **Person:** Most-used pronoun (I / we / you / no-pronoun). If mixed, note the mix.
127
+ 2. **Formality:** Read 5–10 random paragraphs. Place on a scale: casual / approachable_professional / formal / academic.
128
+ 3. **Sentence length:** average, median, p90.
129
+ 4. **Paragraph length:** average sentences per paragraph.
130
+ 5. **Reading grade:** Flesch-Kincaid or similar.
131
+ 6. **Tone descriptors:** 3–5 adjectives based on the corpus. Confident? Cautious? Playful? Direct? Evidence-driven? Storyteller?
132
+ 7. **Signature phrases:** Repeated multi-word phrases that show up across multiple posts. These are the writer's tells.
133
+ 8. **Common openers/closers:** How do paragraphs typically start and end?
134
+ 9. **Lexicon preferred:** Verbs and nouns this writer reaches for. ("ship" instead of "release"; "wire" instead of "integrate"; "land" instead of "launch")
135
+ 10. **Lexicon avoided:** Words *conspicuously absent* from the corpus that competitors or generic AI would use. ("leverage", "synergy", "best-in-class", "innovative", "revolutionary".) The absence is the signal.
136
+ 11. **Punctuation patterns:** em dashes? exclamation marks? oxford comma? parenthetical asides?
137
+ 12. **Structural patterns:** Do posts open with a question? Use headings? Bullet lists? End with a CTA?
138
+
139
+ ### Step 5 — Show the synthesized voice to the user
140
+
141
+ Output a human-readable summary:
142
+
143
+ ```markdown
144
+ ## Brand voice synthesized for {site_url}
145
+
146
+ Based on {n_samples} published posts ({total_words_sampled:,} words sampled, mostly from the last 6 months).
147
+
148
+ **Person:** {person} ("we" / "I" / "you" / mixed)
149
+ **Formality:** {formality}
150
+ **Sentence length:** ~{sentence_length_avg_words} words avg ({sentence_length_p90_words}-word p90)
151
+ **Reading grade:** {reading_grade_avg}
152
+ **Tone:** {tone_descriptors joined}
153
+
154
+ **Signature phrases this site uses repeatedly:**
155
+ {signature_phrases as bulleted list}
156
+
157
+ **Words this site reaches for:**
158
+ {lexicon_preferred as inline list}
159
+
160
+ **Words this site conspicuously avoids:**
161
+ {lexicon_avoided as inline list}
162
+
163
+ **Punctuation quirks:**
164
+ - em dashes: {em_dash_usage}
165
+ - exclamation marks: {exclamation_marks}
166
+ - oxford comma: {oxford_comma}
167
+
168
+ **Structural patterns:**
169
+ - Opens with a question? {opens_with_question}
170
+ - Uses headings? {uses_headings}
171
+ - Ends with a CTA? {ends_with_call_to_action}
172
+
173
+ **A paragraph that sounds like you:**
174
+ > {examples.good_paragraph from the corpus}
175
+
176
+ **A paragraph that does NOT sound like you (generic AI):**
177
+ > {examples.bad_paragraph as a constructed counter-example}
178
+ ```
179
+
180
+ Ask the user: *"Does this match how you'd describe your voice? Anything to add or correct?"*
181
+
182
+ ### Step 6 — Persist to per-site memory
183
+
184
+ The `respira_brand_voice` option is the site's voice memory: it survives across sessions and every future content skill reads it. Persist it carefully.
185
+
186
+ 1. **Diff first.** Read `respira_get_option('respira_brand_voice')`. If a profile already exists, show the user what changed (person, tone, added/removed lexicon) before overwriting — never clobber an existing voice silently.
187
+ 2. **Write.** After confirmation, `respira_update_option('respira_brand_voice', <json>)`.
188
+ 3. **Verify.** Read it back with `respira_get_option('respira_brand_voice')` and confirm it round-tripped.
189
+
190
+ Output: *"Brand voice saved to this site's memory. Every Respira content-writing skill from this point forward will reference it. The avoided-words list is the strongest signal — the agent will refuse to use those words even if the prompt suggests them."*
191
+
192
+ ### Step 7 — Brand-consistency report (optional)
193
+
194
+ The voice profile is also a yardstick: it tells you whether content *already on the site* sounds on-brand. Pull the recent work log with `respira_generate_activity_report` (it returns what was published/edited and when), then sample those pages/posts and score them against the saved profile:
195
+
196
+ - **On-voice:** matches person, sentence length, and reaches for the preferred lexicon.
197
+ - **Off-voice:** uses avoided words, wrong person, or marketing-superlative drift.
198
+
199
+ Report it plainly: *"Of the last 12 published posts, 9 are on-voice. 3 drift toward the avoided lexicon ('revolutionary', 'best-in-class') — likely the templated launch posts. Want me to rewrite those to match?"* This turns the voice profile from a passive artifact into an active consistency check, and pairs naturally with the rewrite skills.
200
+
201
+ ---
202
+
203
+ ## How other skills use the brand voice
204
+
205
+ Once persisted, future content-writing skills (page generators, blog post drafters, social post composers) call `respira_get_option('respira_brand_voice')` at the top of their workflow. They use the voice to:
206
+
207
+ - Pick pronouns matching the site's person
208
+ - Match sentence length and reading grade
209
+ - Reach for the preferred lexicon
210
+ - Refuse to use the avoided lexicon
211
+ - Match punctuation patterns
212
+ - Match structural patterns (open with question? end with CTA?)
213
+
214
+ The **avoided lexicon** is the strongest signal. When the agent is about to write "revolutionary" or "best-in-class," the voice artifact says *"this site never uses that word"* and the agent picks a more honest verb.
215
+
216
+ ### Pairs with
217
+
218
+ The brand voice is one half of the brand foundation. It works best alongside two sibling skills:
219
+
220
+ - **[Design System Synthesizer](https://respira.press/skills/design-system-synthesizer)** — the visual half (colors, typography, spacing, components, stored as `respira_design_system`). Voice covers *how the words read*; the design system covers *how the page looks*. Run both so generated content is on-brand top to bottom. The Design System Synthesizer's style-guide page even links back here for the full voice.
221
+ - **Page Template Library** — when it assembles a page from a saved template, it should read `respira_brand_voice` so the placeholder copy it drops in already sounds like the site, not like lorem-ipsum or generic AI. Voice supplies the words; the template supplies the layout.
222
+
223
+ If only one of the two artifacts exists, content skills should still use what's there — but flag to the user that running the missing synthesizer would tighten the result.
224
+
225
+ ---
226
+
227
+ ## Hard rules
228
+
229
+ - The voice is observed, not designed. Don't invent. Every descriptor traces to evidence in the corpus.
230
+ - The avoided lexicon is the **inverse signal** — words conspicuously absent. Don't include common stop words ("the", "and", "is"). Include words that competitor sites would use heavily but this site doesn't.
231
+ - The "good paragraph" example must be a real paragraph from the corpus, quoted verbatim. The "bad paragraph" example is a constructed counter-example using the avoided lexicon.
232
+ - Never overwrite an existing brand voice silently. Show the diff before saving.
233
+ - If the corpus is mixed-author (multiple writers' voices), say so honestly: *"This site has 3 distinct voices in the sampled posts. Pick one author to synthesize from, or capture all 3 as separate voices."*
234
+
235
+ ---
236
+
237
+ ## Tooling
238
+
239
+ **Reading the corpus (source of truth)**
240
+ - `respira_get_active_site`
241
+ - `respira_get_site_context`
242
+ - `respira_list_posts`
243
+ - `respira_read_post`
244
+ - `respira_extract_builder_content`
245
+
246
+ **Persisting + reporting**
247
+ - `respira_get_option` — diff an existing `respira_brand_voice` before overwriting
248
+ - `respira_update_option` — write the voice profile to per-site memory
249
+ - `respira_generate_activity_report` — recent published/edited work for the brand-consistency check
250
+
251
+ Pairs with the Design System Synthesizer (`respira_design_system` via `respira_get_option`) and the Page Template Library. Use only `respira-wordpress` MCP tools; never invent a tool name.
252
+
253
+ ---
254
+
255
+ ## Telemetry
256
+
257
+ Records: site URL hash, number of posts sampled, total words analyzed, person detected, formality detected, success/failure. No actual phrases, no avoided words, no example paragraphs are sent.
258
+
259
+ Endpoint: `POST https://www.respira.press/api/skills/track-usage`
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "Brand Voice Synthesizer",
3
+ "slug": "brand-voice-synthesizer",
4
+ "icon": "🗣️",
5
+ "category": "intelligence",
6
+ "description": "Read 5-10 published posts and extract the brand voice — tone, lexicon, sentence patterns, person used, formality, signature phrases, phrases the site never uses. Persist it so every future content-writing skill produces copy that sounds like the brand, not like generic AI.",
7
+ "author": "Respira Team",
8
+ "author_url": "https://respira.press",
9
+ "trigger": "extract my brand voice",
10
+ "requires_respira": true,
11
+ "requires_woocommerce_addon": false,
12
+ "requires_accessibility_addon": false,
13
+ "is_read_only": false,
14
+ "is_duplicate_first": false,
15
+ "version": "1.0.0",
16
+ "last_updated": "2026-05-24",
17
+ "tools_used": [
18
+ "respira_get_active_site",
19
+ "respira_get_site_context",
20
+ "respira_list_posts",
21
+ "respira_read_post",
22
+ "respira_extract_builder_content",
23
+ "respira_get_option",
24
+ "respira_update_option"
25
+ ],
26
+ "detects": [
27
+ "person_used",
28
+ "formality_level",
29
+ "sentence_length_distribution",
30
+ "paragraph_length",
31
+ "reading_grade",
32
+ "tone_descriptors",
33
+ "signature_phrases",
34
+ "preferred_lexicon",
35
+ "avoided_lexicon",
36
+ "punctuation_patterns",
37
+ "structural_patterns"
38
+ ],
39
+ "generates": [
40
+ "brand_voice_json",
41
+ "brand_voice_summary_markdown",
42
+ "good_paragraph_example",
43
+ "bad_paragraph_counter_example",
44
+ "persisted_site_option"
45
+ ]
46
+ }
@@ -0,0 +1,59 @@
1
+ # Build an Oxygen 6 Page
2
+
3
+ **Version:** 1.0.0
4
+ **Updated:** 2026-06-16
5
+ **Category:** workflow
6
+ **Status:** stable
7
+ **Requires:** Respira for WordPress plugin (7.4.10+) + MCP server, on a site running Oxygen 6 (Jenga)
8
+ **Telemetry endpoint:** https://www.respira.press/api/skills/track-usage
9
+
10
+ ---
11
+
12
+ ## Description
13
+
14
+ A focused recipe for building or rebuilding pages on **Oxygen 6** (codename Jenga, the Breakdance-based engine), the right way: as native, editable Oxygen elements, not a wall of raw HTML. Oxygen 6 is a different builder from Oxygen Classic, and its structure (separate header, footer, and template post types, a Template Content Area element, an `_oxygen_data` node tree) trips up agents that have not been told how it works. This skill hands you that structure up front so you stop rediscovering it every run and stop falling back to a single HTML code block.
15
+
16
+ Run this when you are about to build or rebuild a page, or a whole site, on an Oxygen 6 install.
17
+
18
+ ---
19
+
20
+ ## When to Use
21
+
22
+ - Building a new page on an Oxygen 6 site.
23
+ - Rebuilding an existing site into Oxygen 6 (for example from a Beaver Builder or Elementor source).
24
+ - A previous attempt produced a blank page, a single HTML/code block, or "Unknown element" / "This content cannot be displayed".
25
+ - Editing the site header, footer, or a template.
26
+
27
+ Do not use this for Oxygen Classic (the `ct_*` shortcode builder); that is a different engine.
28
+
29
+ ---
30
+
31
+ ## How Oxygen 6 is structured (read this first)
32
+
33
+ - **Pages**: a page's layout is a node tree stored in the `_oxygen_data` post meta. You never hand-write that JSON. You pass simplified `type` + `settings` to `build_page` / `inject_builder_content` and Respira maps them onto the real native classes (`OxygenElements\*`, and `EssentialElements\*` when the "Breakdance Elements for Oxygen" add-on is active).
34
+ - **Header / Footer / Templates are separate post types**: `oxygen_header`, `oxygen_footer`, `oxygen_template`. Edit the existing header and footer posts. Do not delete them and re-inline a header and footer into every page.
35
+ - **Templates need a Template Content Area**: an `oxygen_template` must contain a Template Content Area element (`OxygenElements\TemplateContentArea`) at the spot where the page body should render. Do **not** use a Post Content element on Oxygen 6 — it errors and the page cannot be edited. This is the single most common Oxygen 6 mistake.
36
+
37
+ ## The native element vocabulary
38
+
39
+ Author with these simplified types (Respira maps each to the correct native element):
40
+
41
+ `section`, `row`, `column`, `heading` (settings: `text`, `level` h1-h6), `text`, `rich-text`, `button` (settings: `text`, `url`), `image` (settings: `url`), `icon`, `video`, and `code` (a raw HTML snippet — use ONLY for a genuine embed, never for a whole page).
42
+
43
+ Call `respira_get_builder_info` first. On an Oxygen 6 site it returns an `oxygen6` block with the exact per-element schemas and this structure playbook, current for the site.
44
+
45
+ ## Steps
46
+
47
+ 1. **Confirm the builder.** Run `respira_get_builder_info`. Verify it reports Oxygen 6 and read the `oxygen6` block (element schemas + structure).
48
+ 2. **Read before you write.** For an existing page, extract its current tree so you append to or amend the real structure instead of overwriting it. For a rebuild, read the source content.
49
+ 3. **Build native, section by section.** Compose a tree of the simplified types above: a `section` holding `heading` / `text` / `button` / `image`, etc. Use a real `heading` with a `level` for titles, never a styled text block. **Never** put a whole page or section into a single `code` block.
50
+ 4. **Write it.** Use `build_page` for a new page or `inject_builder_content` for an existing one (with `mode: "append"` to add without overwriting, or an explicit replace confirmation to overwrite). Pass `builder: "oxygen"`.
51
+ 5. **Verify it landed.** Re-read the page and confirm the elements are present and render. If a write reports success but the page reads back empty, that is a persistence problem on the host, not a content problem — report it rather than retrying blindly.
52
+ 6. **Header / footer / template.** If the layout needs a shared header or footer, edit the existing `oxygen_header` / `oxygen_footer` posts. If you touch a template, make sure a Template Content Area element is present.
53
+
54
+ ## Anti-patterns (do not do these)
55
+
56
+ - Dumping the whole page into one HTML/code element. It is not editable and defeats the builder.
57
+ - Using a Post Content element in a template on Oxygen 6.
58
+ - Deleting the global header/footer and inlining markup per page.
59
+ - Retrying the same write after a "success but blank" result. Surface it instead.