claude-plugin-wordpress-manager 2.1.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +2 -2
- package/CHANGELOG.md +25 -0
- package/agents/wp-content-strategist.md +30 -0
- package/agents/wp-monitoring-agent.md +50 -0
- package/docs/plans/2026-02-28-wcop-strategic-assessment.md +220 -0
- package/hooks/hooks.json +9 -0
- package/package.json +6 -3
- package/servers/wp-rest-bridge/build/tools/index.d.ts +119 -0
- package/servers/wp-rest-bridge/build/tools/index.js +3 -0
- package/servers/wp-rest-bridge/build/tools/wc-webhooks.d.ts +129 -0
- package/servers/wp-rest-bridge/build/tools/wc-webhooks.js +142 -0
- package/servers/wp-rest-bridge/build/types.d.ts +12 -0
- package/skills/wordpress-router/references/decision-tree.md +7 -3
- package/skills/wp-content/SKILL.md +3 -0
- package/skills/wp-content-repurposing/SKILL.md +96 -0
- package/skills/wp-content-repurposing/references/content-atomization.md +117 -0
- package/skills/wp-content-repurposing/references/email-newsletter.md +136 -0
- package/skills/wp-content-repurposing/references/platform-specs.md +80 -0
- package/skills/wp-content-repurposing/references/social-formats.md +169 -0
- package/skills/wp-content-repurposing/scripts/repurposing_inspect.mjs +140 -0
- package/skills/wp-headless/SKILL.md +1 -0
- package/skills/wp-monitoring/SKILL.md +12 -2
- package/skills/wp-monitoring/references/fleet-monitoring.md +160 -0
- package/skills/wp-monitoring/scripts/monitoring_inspect.mjs +54 -1
- package/skills/wp-webhooks/SKILL.md +107 -0
- package/skills/wp-webhooks/references/integration-recipes.md +176 -0
- package/skills/wp-webhooks/references/payload-formats.md +134 -0
- package/skills/wp-webhooks/references/webhook-security.md +147 -0
- package/skills/wp-webhooks/references/woocommerce-webhooks.md +129 -0
- package/skills/wp-webhooks/references/wordpress-core-webhooks.md +162 -0
- package/skills/wp-webhooks/scripts/webhook_inspect.mjs +157 -0
- package/skills/wp-woocommerce/SKILL.md +1 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
declare const wcListWebhooksSchema: z.ZodObject<{
|
|
4
|
+
status: z.ZodOptional<z.ZodEnum<["active", "paused", "disabled"]>>;
|
|
5
|
+
}, "strict", z.ZodTypeAny, {
|
|
6
|
+
status?: "active" | "paused" | "disabled" | undefined;
|
|
7
|
+
}, {
|
|
8
|
+
status?: "active" | "paused" | "disabled" | undefined;
|
|
9
|
+
}>;
|
|
10
|
+
declare const wcCreateWebhookSchema: z.ZodObject<{
|
|
11
|
+
name: z.ZodString;
|
|
12
|
+
topic: z.ZodString;
|
|
13
|
+
delivery_url: z.ZodString;
|
|
14
|
+
secret: z.ZodOptional<z.ZodString>;
|
|
15
|
+
status: z.ZodOptional<z.ZodEnum<["active", "paused", "disabled"]>>;
|
|
16
|
+
}, "strict", z.ZodTypeAny, {
|
|
17
|
+
name: string;
|
|
18
|
+
topic: string;
|
|
19
|
+
delivery_url: string;
|
|
20
|
+
status?: "active" | "paused" | "disabled" | undefined;
|
|
21
|
+
secret?: string | undefined;
|
|
22
|
+
}, {
|
|
23
|
+
name: string;
|
|
24
|
+
topic: string;
|
|
25
|
+
delivery_url: string;
|
|
26
|
+
status?: "active" | "paused" | "disabled" | undefined;
|
|
27
|
+
secret?: string | undefined;
|
|
28
|
+
}>;
|
|
29
|
+
declare const wcUpdateWebhookSchema: z.ZodObject<{
|
|
30
|
+
id: z.ZodNumber;
|
|
31
|
+
name: z.ZodOptional<z.ZodString>;
|
|
32
|
+
topic: z.ZodOptional<z.ZodString>;
|
|
33
|
+
delivery_url: z.ZodOptional<z.ZodString>;
|
|
34
|
+
secret: z.ZodOptional<z.ZodString>;
|
|
35
|
+
status: z.ZodOptional<z.ZodEnum<["active", "paused", "disabled"]>>;
|
|
36
|
+
}, "strict", z.ZodTypeAny, {
|
|
37
|
+
id: number;
|
|
38
|
+
status?: "active" | "paused" | "disabled" | undefined;
|
|
39
|
+
name?: string | undefined;
|
|
40
|
+
topic?: string | undefined;
|
|
41
|
+
delivery_url?: string | undefined;
|
|
42
|
+
secret?: string | undefined;
|
|
43
|
+
}, {
|
|
44
|
+
id: number;
|
|
45
|
+
status?: "active" | "paused" | "disabled" | undefined;
|
|
46
|
+
name?: string | undefined;
|
|
47
|
+
topic?: string | undefined;
|
|
48
|
+
delivery_url?: string | undefined;
|
|
49
|
+
secret?: string | undefined;
|
|
50
|
+
}>;
|
|
51
|
+
declare const wcDeleteWebhookSchema: z.ZodObject<{
|
|
52
|
+
id: z.ZodNumber;
|
|
53
|
+
}, "strict", z.ZodTypeAny, {
|
|
54
|
+
id: number;
|
|
55
|
+
}, {
|
|
56
|
+
id: number;
|
|
57
|
+
}>;
|
|
58
|
+
export declare const wcWebhookTools: Tool[];
|
|
59
|
+
export declare const wcWebhookHandlers: {
|
|
60
|
+
wc_list_webhooks: (params: z.infer<typeof wcListWebhooksSchema>) => Promise<{
|
|
61
|
+
toolResult: {
|
|
62
|
+
content: {
|
|
63
|
+
type: string;
|
|
64
|
+
text: string;
|
|
65
|
+
}[];
|
|
66
|
+
isError?: undefined;
|
|
67
|
+
};
|
|
68
|
+
} | {
|
|
69
|
+
toolResult: {
|
|
70
|
+
isError: boolean;
|
|
71
|
+
content: {
|
|
72
|
+
type: string;
|
|
73
|
+
text: string;
|
|
74
|
+
}[];
|
|
75
|
+
};
|
|
76
|
+
}>;
|
|
77
|
+
wc_create_webhook: (params: z.infer<typeof wcCreateWebhookSchema>) => Promise<{
|
|
78
|
+
toolResult: {
|
|
79
|
+
content: {
|
|
80
|
+
type: string;
|
|
81
|
+
text: string;
|
|
82
|
+
}[];
|
|
83
|
+
isError?: undefined;
|
|
84
|
+
};
|
|
85
|
+
} | {
|
|
86
|
+
toolResult: {
|
|
87
|
+
isError: boolean;
|
|
88
|
+
content: {
|
|
89
|
+
type: string;
|
|
90
|
+
text: string;
|
|
91
|
+
}[];
|
|
92
|
+
};
|
|
93
|
+
}>;
|
|
94
|
+
wc_update_webhook: (params: z.infer<typeof wcUpdateWebhookSchema>) => Promise<{
|
|
95
|
+
toolResult: {
|
|
96
|
+
content: {
|
|
97
|
+
type: string;
|
|
98
|
+
text: string;
|
|
99
|
+
}[];
|
|
100
|
+
isError?: undefined;
|
|
101
|
+
};
|
|
102
|
+
} | {
|
|
103
|
+
toolResult: {
|
|
104
|
+
isError: boolean;
|
|
105
|
+
content: {
|
|
106
|
+
type: string;
|
|
107
|
+
text: string;
|
|
108
|
+
}[];
|
|
109
|
+
};
|
|
110
|
+
}>;
|
|
111
|
+
wc_delete_webhook: (params: z.infer<typeof wcDeleteWebhookSchema>) => Promise<{
|
|
112
|
+
toolResult: {
|
|
113
|
+
content: {
|
|
114
|
+
type: string;
|
|
115
|
+
text: string;
|
|
116
|
+
}[];
|
|
117
|
+
isError?: undefined;
|
|
118
|
+
};
|
|
119
|
+
} | {
|
|
120
|
+
toolResult: {
|
|
121
|
+
isError: boolean;
|
|
122
|
+
content: {
|
|
123
|
+
type: string;
|
|
124
|
+
text: string;
|
|
125
|
+
}[];
|
|
126
|
+
};
|
|
127
|
+
}>;
|
|
128
|
+
};
|
|
129
|
+
export {};
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { makeWooCommerceRequest } from '../wordpress.js';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
const wcListWebhooksSchema = z.object({
|
|
4
|
+
status: z.enum(['active', 'paused', 'disabled']).optional()
|
|
5
|
+
.describe('Filter webhooks by status'),
|
|
6
|
+
}).strict();
|
|
7
|
+
const wcCreateWebhookSchema = z.object({
|
|
8
|
+
name: z.string().describe('Webhook name (for identification)'),
|
|
9
|
+
topic: z.string().describe('Event topic, e.g. "order.created", "product.updated"'),
|
|
10
|
+
delivery_url: z.string().describe('URL to receive the webhook payload'),
|
|
11
|
+
secret: z.string().optional().describe('Secret for HMAC-SHA256 signature verification'),
|
|
12
|
+
status: z.enum(['active', 'paused', 'disabled']).optional()
|
|
13
|
+
.describe('Webhook status (default: active)'),
|
|
14
|
+
}).strict();
|
|
15
|
+
const wcUpdateWebhookSchema = z.object({
|
|
16
|
+
id: z.number().describe('Webhook ID to update'),
|
|
17
|
+
name: z.string().optional().describe('Updated webhook name'),
|
|
18
|
+
topic: z.string().optional().describe('Updated event topic'),
|
|
19
|
+
delivery_url: z.string().optional().describe('Updated delivery URL'),
|
|
20
|
+
secret: z.string().optional().describe('Updated secret'),
|
|
21
|
+
status: z.enum(['active', 'paused', 'disabled']).optional()
|
|
22
|
+
.describe('Updated webhook status'),
|
|
23
|
+
}).strict();
|
|
24
|
+
const wcDeleteWebhookSchema = z.object({
|
|
25
|
+
id: z.number().describe('Webhook ID to delete'),
|
|
26
|
+
}).strict();
|
|
27
|
+
export const wcWebhookTools = [
|
|
28
|
+
{
|
|
29
|
+
name: "wc_list_webhooks",
|
|
30
|
+
description: "Lists all WooCommerce webhooks with their status, topic, and delivery URL",
|
|
31
|
+
inputSchema: {
|
|
32
|
+
type: "object",
|
|
33
|
+
properties: {
|
|
34
|
+
status: {
|
|
35
|
+
type: "string",
|
|
36
|
+
enum: ["active", "paused", "disabled"],
|
|
37
|
+
description: "Filter webhooks by status",
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: "wc_create_webhook",
|
|
44
|
+
description: "Creates a new WooCommerce webhook for event notifications (e.g. order.created, product.updated)",
|
|
45
|
+
inputSchema: {
|
|
46
|
+
type: "object",
|
|
47
|
+
properties: {
|
|
48
|
+
name: { type: "string", description: "Webhook name (for identification)" },
|
|
49
|
+
topic: { type: "string", description: "Event topic, e.g. 'order.created', 'product.updated'" },
|
|
50
|
+
delivery_url: { type: "string", description: "URL to receive the webhook payload" },
|
|
51
|
+
secret: { type: "string", description: "Secret for HMAC-SHA256 signature verification" },
|
|
52
|
+
status: {
|
|
53
|
+
type: "string",
|
|
54
|
+
enum: ["active", "paused", "disabled"],
|
|
55
|
+
description: "Webhook status (default: active)",
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
required: ["name", "topic", "delivery_url"],
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
name: "wc_update_webhook",
|
|
63
|
+
description: "Updates an existing WooCommerce webhook (status, delivery URL, topic, etc.)",
|
|
64
|
+
inputSchema: {
|
|
65
|
+
type: "object",
|
|
66
|
+
properties: {
|
|
67
|
+
id: { type: "number", description: "Webhook ID to update" },
|
|
68
|
+
name: { type: "string", description: "Updated webhook name" },
|
|
69
|
+
topic: { type: "string", description: "Updated event topic" },
|
|
70
|
+
delivery_url: { type: "string", description: "Updated delivery URL" },
|
|
71
|
+
secret: { type: "string", description: "Updated secret" },
|
|
72
|
+
status: {
|
|
73
|
+
type: "string",
|
|
74
|
+
enum: ["active", "paused", "disabled"],
|
|
75
|
+
description: "Updated webhook status",
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
required: ["id"],
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: "wc_delete_webhook",
|
|
83
|
+
description: "Deletes a WooCommerce webhook (stops notifications to the delivery URL)",
|
|
84
|
+
inputSchema: {
|
|
85
|
+
type: "object",
|
|
86
|
+
properties: {
|
|
87
|
+
id: { type: "number", description: "Webhook ID to delete" },
|
|
88
|
+
},
|
|
89
|
+
required: ["id"],
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
];
|
|
93
|
+
export const wcWebhookHandlers = {
|
|
94
|
+
wc_list_webhooks: async (params) => {
|
|
95
|
+
try {
|
|
96
|
+
const query = params.status ? `?status=${params.status}` : '';
|
|
97
|
+
const response = await makeWooCommerceRequest("GET", `webhooks${query}`);
|
|
98
|
+
return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
const errorMessage = error.response?.data?.message || error.message;
|
|
102
|
+
return { toolResult: { isError: true, content: [{ type: "text", text: `Error listing webhooks: ${errorMessage}` }] } };
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
wc_create_webhook: async (params) => {
|
|
106
|
+
try {
|
|
107
|
+
const { name, topic, delivery_url, secret, status } = params;
|
|
108
|
+
const body = { name, topic, delivery_url };
|
|
109
|
+
if (secret)
|
|
110
|
+
body.secret = secret;
|
|
111
|
+
if (status)
|
|
112
|
+
body.status = status;
|
|
113
|
+
const response = await makeWooCommerceRequest("POST", "webhooks", body);
|
|
114
|
+
return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
const errorMessage = error.response?.data?.message || error.message;
|
|
118
|
+
return { toolResult: { isError: true, content: [{ type: "text", text: `Error creating webhook: ${errorMessage}` }] } };
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
wc_update_webhook: async (params) => {
|
|
122
|
+
try {
|
|
123
|
+
const { id, ...updates } = params;
|
|
124
|
+
const response = await makeWooCommerceRequest("PUT", `webhooks/${id}`, updates);
|
|
125
|
+
return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
const errorMessage = error.response?.data?.message || error.message;
|
|
129
|
+
return { toolResult: { isError: true, content: [{ type: "text", text: `Error updating webhook: ${errorMessage}` }] } };
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
wc_delete_webhook: async (params) => {
|
|
133
|
+
try {
|
|
134
|
+
const response = await makeWooCommerceRequest("DELETE", `webhooks/${params.id}?force=true`);
|
|
135
|
+
return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
const errorMessage = error.response?.data?.message || error.message;
|
|
139
|
+
return { toolResult: { isError: true, content: [{ type: "text", text: `Error deleting webhook: ${errorMessage}` }] } };
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
};
|
|
@@ -233,6 +233,18 @@ export interface WCCoupon {
|
|
|
233
233
|
minimum_amount: string;
|
|
234
234
|
maximum_amount: string;
|
|
235
235
|
}
|
|
236
|
+
export interface WCWebhook {
|
|
237
|
+
id: number;
|
|
238
|
+
name: string;
|
|
239
|
+
status: string;
|
|
240
|
+
topic: string;
|
|
241
|
+
resource: string;
|
|
242
|
+
event: string;
|
|
243
|
+
delivery_url: string;
|
|
244
|
+
secret: string;
|
|
245
|
+
date_created: string;
|
|
246
|
+
date_modified: string;
|
|
247
|
+
}
|
|
236
248
|
export interface WPNetworkSite {
|
|
237
249
|
blog_id: number;
|
|
238
250
|
url: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Router decision tree (
|
|
1
|
+
# Router decision tree (v9 — development + local environment + operations + multisite + CI/CD + monitoring + webhooks + content repurposing)
|
|
2
2
|
|
|
3
3
|
This routing guide covers WordPress **development**, **local environment**, and **operations** workflows.
|
|
4
4
|
|
|
@@ -14,7 +14,7 @@ Keywords that indicate **local environment**:
|
|
|
14
14
|
local site, Studio, LocalWP, Local by Flywheel, wp-env, local WordPress, start site, stop site, create local site, local development, symlink plugin, local database, switch PHP version, localhost, local preview, detect environment, WASM, SQLite local
|
|
15
15
|
|
|
16
16
|
Keywords that indicate **operations**:
|
|
17
|
-
deploy, push to production, audit, security check, backup, restore, migrate, move site, create post, manage content, site status, check plugins, performance check, SEO audit, WooCommerce, prodotto, ordine, coupon, negozio, catalogo, inventario, vendite, carrello, multisite, network, sub-site, sub-sito, domain mapping, super admin, network activate, monitor, uptime, health report, trend, scansione periodica, alerting, performance baseline
|
|
17
|
+
deploy, push to production, audit, security check, backup, restore, migrate, move site, create post, manage content, site status, check plugins, performance check, SEO audit, WooCommerce, prodotto, ordine, coupon, negozio, catalogo, inventario, vendite, carrello, multisite, network, sub-site, sub-sito, domain mapping, super admin, network activate, monitor, uptime, health report, trend, scansione periodica, alerting, performance baseline, fleet, all sites, network health, cross-site, webhook, outbound notification, event propagation, Zapier, content sync, repurpose content, social posts from blog, content atomization, newsletter from posts, content distribution
|
|
18
18
|
|
|
19
19
|
Keywords that indicate **development**:
|
|
20
20
|
create block, block.json, theme.json, register_rest_route, plugin development, hooks, PHPStan, build, test, scaffold, i18n, translation, accessibility, a11y, headless, decoupled, WPGraphQL, CI, CD, pipeline, GitHub Actions, GitLab CI, deploy automatico, workflow, quality gate
|
|
@@ -92,8 +92,12 @@ Priority: `gutenberg` > `wp-core` > `wp-site` > `wp-block-theme` > `wp-block-plu
|
|
|
92
92
|
→ `wp-woocommerce` skill + `wp-ecommerce-manager` agent
|
|
93
93
|
- **Multisite / network / sub-sites / domain mapping / super admin / network activate**
|
|
94
94
|
→ `wp-multisite` skill + `wp-site-manager` agent
|
|
95
|
-
- **Monitor / uptime / health report / trend / scansione periodica / alerting / performance baseline / ongoing checks**
|
|
95
|
+
- **Monitor / uptime / health report / trend / scansione periodica / alerting / performance baseline / ongoing checks / fleet / all sites / cross-site comparison**
|
|
96
96
|
→ `wp-monitoring` skill + `wp-monitoring-agent` agent
|
|
97
|
+
- **Webhook / outbound notification / event propagation / Zapier / Make / n8n / content sync webhook**
|
|
98
|
+
→ `wp-webhooks` skill + `wp-site-manager` agent
|
|
99
|
+
- **Repurpose content / social posts from blog / newsletter from content / atomize / content distribution / turn blog into social**
|
|
100
|
+
→ `wp-content-repurposing` skill + `wp-content-strategist` agent
|
|
97
101
|
|
|
98
102
|
## Step 2c: route by local environment intent (keywords)
|
|
99
103
|
|
|
@@ -101,3 +101,6 @@ Tool: assign_terms_to_content — assign terms to content
|
|
|
101
101
|
### Reference Files
|
|
102
102
|
- **`references/content-templates.md`** - Templates for different content types
|
|
103
103
|
- **`references/seo-optimization.md`** - On-page SEO patterns for WordPress
|
|
104
|
+
|
|
105
|
+
### Related Skills
|
|
106
|
+
- **`wp-content-repurposing`** — transform existing content for social media, email, and multi-channel distribution
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wp-content-repurposing
|
|
3
|
+
description: This skill should be used when the user asks to "repurpose content",
|
|
4
|
+
"create social posts from blog", "transform content for social media", "email
|
|
5
|
+
newsletter from posts", "content atomization", "reuse content across channels",
|
|
6
|
+
"adapt content for different platforms", "turn blog into social", "content
|
|
7
|
+
distribution", or mentions turning WordPress content into multi-format outputs.
|
|
8
|
+
version: 1.0.0
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# WordPress Content Repurposing Skill
|
|
12
|
+
|
|
13
|
+
## Overview
|
|
14
|
+
|
|
15
|
+
Content repurposing is the systematic transformation of canonical WordPress content into channel-specific formats. Instead of creating original content for each platform, you extract value from existing posts, pages, and products and reshape it for social media, email newsletters, ad copy, and other distribution channels.
|
|
16
|
+
|
|
17
|
+
## When to Use
|
|
18
|
+
|
|
19
|
+
- User has existing WordPress content and wants to distribute it across channels
|
|
20
|
+
- User asks to turn blog posts into social media content
|
|
21
|
+
- User wants to create email newsletters from existing content
|
|
22
|
+
- User needs to atomize long-form content into smaller shareable pieces
|
|
23
|
+
- User wants platform-specific content variants from a single source
|
|
24
|
+
|
|
25
|
+
## Content Repurposing vs Content Creation
|
|
26
|
+
|
|
27
|
+
| Need | Skill |
|
|
28
|
+
|------|-------|
|
|
29
|
+
| Create new original content from scratch | `wp-content` |
|
|
30
|
+
| Transform existing content for new channels | `wp-content-repurposing` (this skill) |
|
|
31
|
+
| SEO-optimized blog post creation | `wp-content` |
|
|
32
|
+
| Blog post → social thread + email digest | `wp-content-repurposing` (this skill) |
|
|
33
|
+
|
|
34
|
+
## Decision Tree
|
|
35
|
+
|
|
36
|
+
1. **What output format?**
|
|
37
|
+
- "social posts" / "Twitter thread" / "LinkedIn" / "Instagram" → Social formats (Section 1)
|
|
38
|
+
- "email" / "newsletter" / "digest" → Email newsletter (Section 2)
|
|
39
|
+
- "atomize" / "break down" / "content calendar" → Content atomization (Section 3)
|
|
40
|
+
- "character limits" / "platform specs" / "image sizes" → Platform specifications (Section 4)
|
|
41
|
+
|
|
42
|
+
2. **Run detection first:**
|
|
43
|
+
```bash
|
|
44
|
+
node skills/wp-content-repurposing/scripts/repurposing_inspect.mjs [--cwd=/path/to/project]
|
|
45
|
+
```
|
|
46
|
+
This identifies existing content volume, social plugins, and email integrations.
|
|
47
|
+
|
|
48
|
+
## Repurposing Areas
|
|
49
|
+
|
|
50
|
+
### Section 1: Social Formats
|
|
51
|
+
See `references/social-formats.md`
|
|
52
|
+
- Blog post → Twitter/X thread
|
|
53
|
+
- Blog post → LinkedIn article summary
|
|
54
|
+
- Blog post → Instagram carousel
|
|
55
|
+
- Blog post → Facebook engagement post
|
|
56
|
+
- Product → social proof posts
|
|
57
|
+
|
|
58
|
+
### Section 2: Email Newsletter
|
|
59
|
+
See `references/email-newsletter.md`
|
|
60
|
+
- Blog post → newsletter digest
|
|
61
|
+
- Product launch → email announcement
|
|
62
|
+
- Content series → drip sequence
|
|
63
|
+
- Subject line and CTA optimization
|
|
64
|
+
|
|
65
|
+
### Section 3: Content Atomization
|
|
66
|
+
See `references/content-atomization.md`
|
|
67
|
+
- Pillar content → atomic units (quotes, stats, tips)
|
|
68
|
+
- Atomization workflow and content calendar
|
|
69
|
+
- Repurposing matrix (1 post → 5-10 outputs)
|
|
70
|
+
- Quality gates for standalone value
|
|
71
|
+
|
|
72
|
+
### Section 4: Platform Specifications
|
|
73
|
+
See `references/platform-specs.md`
|
|
74
|
+
- Character limits per platform
|
|
75
|
+
- Image dimensions per platform
|
|
76
|
+
- Hashtag and link strategies
|
|
77
|
+
- Posting frequency recommendations
|
|
78
|
+
|
|
79
|
+
## Reference Files
|
|
80
|
+
|
|
81
|
+
| File | Content |
|
|
82
|
+
|------|---------|
|
|
83
|
+
| `references/social-formats.md` | Templates for Twitter, LinkedIn, Instagram, Facebook |
|
|
84
|
+
| `references/email-newsletter.md` | Newsletter digest, drip sequences, subject lines |
|
|
85
|
+
| `references/content-atomization.md` | Atomization workflow, content calendar, repurposing matrix |
|
|
86
|
+
| `references/platform-specs.md` | Character limits, image sizes, posting frequency |
|
|
87
|
+
|
|
88
|
+
## Recommended Agent
|
|
89
|
+
|
|
90
|
+
**`wp-content-strategist`** — selects source content via WP REST Bridge, extracts key elements, applies platform templates, and generates formatted outputs for review.
|
|
91
|
+
|
|
92
|
+
## Related Skills
|
|
93
|
+
|
|
94
|
+
- **`wp-content`** — content creation and lifecycle management (source content)
|
|
95
|
+
- **`wp-headless`** — headless content delivery for multi-channel architectures
|
|
96
|
+
- **`wp-woocommerce`** — product content for e-commerce repurposing
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Content Atomization
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Content atomization is the process of breaking down pillar content (long-form blog posts, guides, product pages) into standalone atomic units that each deliver value independently. One pillar post can yield 5-15 atomic pieces for distribution across multiple channels.
|
|
6
|
+
|
|
7
|
+
## Atomization Workflow
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
1. SELECT source content (pillar post)
|
|
11
|
+
|
|
|
12
|
+
2. IDENTIFY atomic elements (quotes, stats, tips, questions)
|
|
13
|
+
|
|
|
14
|
+
3. EXTRACT and format each atom
|
|
15
|
+
|
|
|
16
|
+
4. ASSIGN to channels (social, email, ad copy)
|
|
17
|
+
|
|
|
18
|
+
5. SCHEDULE via content calendar
|
|
19
|
+
|
|
|
20
|
+
6. DISTRIBUTE and track performance
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Step 1: Select Source Content
|
|
24
|
+
|
|
25
|
+
Prioritize content that is:
|
|
26
|
+
- **Evergreen**: valuable regardless of timing
|
|
27
|
+
- **Data-rich**: contains statistics, quotes, or unique insights
|
|
28
|
+
- **Popular**: already proven with traffic or engagement
|
|
29
|
+
- **Long-form**: 1,000+ words with multiple sections
|
|
30
|
+
|
|
31
|
+
Use `list_content` with `orderby: "date"` or traffic data to identify top candidates.
|
|
32
|
+
|
|
33
|
+
### Step 2: Identify Atomic Elements
|
|
34
|
+
|
|
35
|
+
| Element Type | What to Look For | Output Count |
|
|
36
|
+
|-------------|-----------------|--------------|
|
|
37
|
+
| Key quotes | Standalone insightful sentences | 2-4 per post |
|
|
38
|
+
| Statistics | Numbers, percentages, data points | 1-3 per post |
|
|
39
|
+
| Tips/How-tos | Actionable advice steps | 3-5 per post |
|
|
40
|
+
| Questions | Thought-provoking questions | 1-2 per post |
|
|
41
|
+
| Lists | Numbered or bulleted lists | 1-2 per post |
|
|
42
|
+
| Definitions | Explained concepts or terms | 1-2 per post |
|
|
43
|
+
|
|
44
|
+
### Step 3: Extract and Format
|
|
45
|
+
|
|
46
|
+
For each atom, create a self-contained piece:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
ATOM CARD:
|
|
50
|
+
- Source: [post title + URL]
|
|
51
|
+
- Type: [quote / stat / tip / question]
|
|
52
|
+
- Content: [the atomic content, 1-3 sentences]
|
|
53
|
+
- Channel: [Twitter / LinkedIn / Instagram / Email / Ad]
|
|
54
|
+
- Visual needed: [yes/no, description if yes]
|
|
55
|
+
- CTA: [link back to full post]
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Step 4: Assign to Channels
|
|
59
|
+
|
|
60
|
+
Map atom types to their best channels:
|
|
61
|
+
|
|
62
|
+
| Atom Type | Best Channels | Format |
|
|
63
|
+
|-----------|--------------|--------|
|
|
64
|
+
| Quote | Twitter, Instagram, LinkedIn | Image with text overlay or plain text |
|
|
65
|
+
| Statistic | Twitter, LinkedIn, Facebook | Data visualization or bold text |
|
|
66
|
+
| Tip | All channels | Step-by-step or bullet list |
|
|
67
|
+
| Question | Twitter, LinkedIn, Facebook | Engagement post |
|
|
68
|
+
| List | Instagram carousel, LinkedIn | Multi-slide or numbered |
|
|
69
|
+
|
|
70
|
+
## Repurposing Matrix
|
|
71
|
+
|
|
72
|
+
One blog post (1,500+ words) can produce:
|
|
73
|
+
|
|
74
|
+
| Output | Count | Channel |
|
|
75
|
+
|--------|-------|---------|
|
|
76
|
+
| Twitter/X thread | 1 | Twitter |
|
|
77
|
+
| Individual tweets | 3-5 | Twitter |
|
|
78
|
+
| LinkedIn post | 1-2 | LinkedIn |
|
|
79
|
+
| Instagram carousel | 1 | Instagram |
|
|
80
|
+
| Facebook post | 1 | Facebook |
|
|
81
|
+
| Email digest section | 1 | Newsletter |
|
|
82
|
+
| Pull quotes for ads | 2-3 | Paid social |
|
|
83
|
+
| **Total outputs** | **10-15** | — |
|
|
84
|
+
|
|
85
|
+
## Content Calendar Integration
|
|
86
|
+
|
|
87
|
+
### Weekly Schedule from One Post
|
|
88
|
+
|
|
89
|
+
| Day | Content | Channel | Atom Type |
|
|
90
|
+
|-----|---------|---------|-----------|
|
|
91
|
+
| Mon | Full thread | Twitter | All key points |
|
|
92
|
+
| Tue | Article summary | LinkedIn | Overview |
|
|
93
|
+
| Wed | Carousel | Instagram | Visual takeaways |
|
|
94
|
+
| Thu | Engagement post | Facebook | Question |
|
|
95
|
+
| Fri | Individual quote | Twitter | Best quote |
|
|
96
|
+
| Sat | — | — | Rest day |
|
|
97
|
+
| Sun | Email digest | Newsletter | Summary + CTA |
|
|
98
|
+
|
|
99
|
+
### Monthly Cadence
|
|
100
|
+
|
|
101
|
+
- **Week 1**: Publish pillar post + immediate social promotion
|
|
102
|
+
- **Week 2**: Atomized social content from Week 1 post
|
|
103
|
+
- **Week 3**: Publish new pillar post + atomize Week 1 remainder
|
|
104
|
+
- **Week 4**: Cross-promote best performers + email roundup
|
|
105
|
+
|
|
106
|
+
## Quality Gates
|
|
107
|
+
|
|
108
|
+
Each atomic piece must pass these checks:
|
|
109
|
+
|
|
110
|
+
1. **Standalone value**: Does it make sense without the source article?
|
|
111
|
+
2. **Single idea**: Does it convey exactly one concept?
|
|
112
|
+
3. **Actionable or insightful**: Does it teach, inspire, or provoke thought?
|
|
113
|
+
4. **Channel-appropriate**: Does it fit the platform's format and audience?
|
|
114
|
+
5. **Brand-consistent**: Does it match the brand voice and visual style?
|
|
115
|
+
6. **Attribution**: Does it link back to the source when appropriate?
|
|
116
|
+
|
|
117
|
+
If an atom fails any gate, revise or discard it.
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Email Newsletter Templates
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Templates for transforming WordPress content into email-ready formats. Covers newsletter digests, product announcements, and drip sequences.
|
|
6
|
+
|
|
7
|
+
## Blog Post → Newsletter Digest
|
|
8
|
+
|
|
9
|
+
**Template:**
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
Subject: [Keyword] — [Benefit or curiosity hook]
|
|
13
|
+
Preview text: [First 90 chars that complement the subject line]
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
Hi [first_name],
|
|
18
|
+
|
|
19
|
+
[1-2 sentence personal intro connecting to the topic]
|
|
20
|
+
|
|
21
|
+
## [Post Title]
|
|
22
|
+
|
|
23
|
+
[3-4 sentence excerpt highlighting the most valuable insight]
|
|
24
|
+
|
|
25
|
+
[Key quote or statistic from the post]
|
|
26
|
+
|
|
27
|
+
Read the full article: [link]
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Quick Tip
|
|
32
|
+
|
|
33
|
+
[One actionable takeaway from the post that works standalone]
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
[Sign-off]
|
|
38
|
+
[Company/brand name]
|
|
39
|
+
|
|
40
|
+
[Unsubscribe link]
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**Rules:**
|
|
44
|
+
- Subject line: 40-60 characters, include primary keyword
|
|
45
|
+
- Preview text: 40-90 characters, complements (not repeats) subject
|
|
46
|
+
- Body: 200-300 words max
|
|
47
|
+
- One primary CTA (link to post)
|
|
48
|
+
- Mobile-friendly: single column, large buttons
|
|
49
|
+
|
|
50
|
+
## Product Launch → Email Announcement
|
|
51
|
+
|
|
52
|
+
**Template:**
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
Subject: Introducing [Product Name] — [One-line value prop]
|
|
56
|
+
Preview text: [Benefit] + [urgency or exclusivity]
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
Hi [first_name],
|
|
61
|
+
|
|
62
|
+
We're excited to announce [Product Name].
|
|
63
|
+
|
|
64
|
+
## What it is
|
|
65
|
+
[2-3 sentences describing the product]
|
|
66
|
+
|
|
67
|
+
## Why you'll love it
|
|
68
|
+
- [Benefit 1]
|
|
69
|
+
- [Benefit 2]
|
|
70
|
+
- [Benefit 3]
|
|
71
|
+
|
|
72
|
+
## Special offer
|
|
73
|
+
[Launch pricing, early access, or bonus]
|
|
74
|
+
|
|
75
|
+
[CTA Button: Shop Now / Learn More]
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
[Social proof: "Join X customers who already..."]
|
|
80
|
+
|
|
81
|
+
[Sign-off]
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Content Series → Drip Sequence
|
|
85
|
+
|
|
86
|
+
**Template (3-email sequence from a pillar post):**
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
Email 1 — Day 0 (Hook):
|
|
90
|
+
Subject: The [topic] guide you've been waiting for
|
|
91
|
+
Body: Introduce the pillar topic, deliver first key insight,
|
|
92
|
+
tease what's coming in the next emails.
|
|
93
|
+
CTA: Read Part 1
|
|
94
|
+
|
|
95
|
+
Email 2 — Day 3 (Deep Dive):
|
|
96
|
+
Subject: [Specific technique] from our [topic] guide
|
|
97
|
+
Body: Expand on the most actionable section of the post,
|
|
98
|
+
provide step-by-step instructions or examples.
|
|
99
|
+
CTA: Read Part 2 / Try it now
|
|
100
|
+
|
|
101
|
+
Email 3 — Day 7 (Summary + CTA):
|
|
102
|
+
Subject: Everything you need to know about [topic]
|
|
103
|
+
Body: Recap key takeaways, link to full article,
|
|
104
|
+
offer next step (product, consultation, download).
|
|
105
|
+
CTA: Get the complete guide / Shop related products
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Subject Line Formulas
|
|
109
|
+
|
|
110
|
+
| Formula | Example |
|
|
111
|
+
|---------|---------|
|
|
112
|
+
| Number + Benefit | "5 ways to reduce sugar intake" |
|
|
113
|
+
| Question | "Is cactus water the healthiest option?" |
|
|
114
|
+
| How-to | "How to save 200 calories a day" |
|
|
115
|
+
| Curiosity gap | "The drink we didn't expect to love" |
|
|
116
|
+
| Urgency | "Last chance: 20% off ends tonight" |
|
|
117
|
+
| Personal | "[Name], we picked this for you" |
|
|
118
|
+
|
|
119
|
+
## Segmentation Considerations
|
|
120
|
+
|
|
121
|
+
Match content type to audience segment:
|
|
122
|
+
|
|
123
|
+
| Content Type | Best Segment | Email Focus |
|
|
124
|
+
|--------------|-------------|-------------|
|
|
125
|
+
| Blog post (educational) | All subscribers | Knowledge + CTA to site |
|
|
126
|
+
| Product update | Past customers | Features + upgrade path |
|
|
127
|
+
| Industry news | Engaged readers | Commentary + discussion |
|
|
128
|
+
| Case study | Prospects | Results + trial CTA |
|
|
129
|
+
| Seasonal content | Active in last 90 days | Timely offers |
|
|
130
|
+
|
|
131
|
+
## Key Metrics
|
|
132
|
+
|
|
133
|
+
- **Open rate target**: 20-25% (industry avg)
|
|
134
|
+
- **Click rate target**: 2-5%
|
|
135
|
+
- **Unsubscribe rate**: keep below 0.5% per send
|
|
136
|
+
- **Best send times**: Tuesday-Thursday, 9-11 AM local time
|