claude-plugin-wordpress-manager 2.12.2 → 2.13.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 +8 -3
- package/CHANGELOG.md +55 -0
- package/docs/GUIDE.md +240 -1
- package/docs/VALIDATION.md +341 -0
- package/docs/plans/2026-03-02-content-framework-architecture.md +612 -0
- package/docs/plans/2026-03-02-content-framework-strategic-reflections.md +228 -0
- package/docs/plans/2026-03-02-content-intelligence-phase2.md +560 -0
- package/docs/plans/2026-03-02-content-pipeline-phase1.md +456 -0
- package/docs/plans/2026-03-02-editorial-calendar-phase3.md +490 -0
- package/docs/validation/.gitkeep +0 -0
- package/docs/validation/dashboard.html +286 -0
- package/docs/validation/results.json +1705 -0
- package/package.json +12 -3
- package/scripts/run-validation.mjs +1132 -0
- package/servers/wp-rest-bridge/build/server.js +16 -5
- package/servers/wp-rest-bridge/build/tools/index.js +0 -9
- package/servers/wp-rest-bridge/build/tools/plugin-repository.js +23 -31
- package/servers/wp-rest-bridge/build/tools/schema.js +10 -2
- package/servers/wp-rest-bridge/build/tools/unified-content.js +10 -2
- package/servers/wp-rest-bridge/build/wordpress.d.ts +0 -3
- package/servers/wp-rest-bridge/build/wordpress.js +16 -98
- package/servers/wp-rest-bridge/package.json +1 -0
- package/skills/wp-analytics/SKILL.md +153 -0
- package/skills/wp-analytics/references/signals-feed-schema.md +417 -0
- package/skills/wp-content-pipeline/SKILL.md +461 -0
- package/skills/wp-content-pipeline/references/content-brief-schema.md +377 -0
- package/skills/wp-content-pipeline/references/site-config-schema.md +431 -0
- package/skills/wp-editorial-planner/SKILL.md +262 -0
- package/skills/wp-editorial-planner/references/editorial-schema.md +268 -0
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
# Editorial Calendar Schema
|
|
2
|
+
|
|
3
|
+
Schema reference for `{YYYY-MM}-editorial.state.md` files -- the monthly editorial calendar format used by the `wp-editorial-planner` skill to plan, track, and synchronize content across the publishing lifecycle.
|
|
4
|
+
|
|
5
|
+
Each editorial calendar is a Markdown file with YAML frontmatter containing monthly goals and metadata, followed by weekly Markdown tables for content planning. Each table row represents a content entry that progresses through a five-stage status lifecycle and bridges to Phase 1 briefs (`.brief.md` files in the content pipeline) and Phase 2 signals (from the signals intelligence feed).
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## File Format
|
|
10
|
+
|
|
11
|
+
Each `{YYYY-MM}-editorial.state.md` file consists of:
|
|
12
|
+
|
|
13
|
+
1. **YAML frontmatter** between `---` delimiters (monthly goals, metadata, SEO targets)
|
|
14
|
+
2. **Markdown body** with weekly table sections, one per week of the month
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
---
|
|
18
|
+
calendar_id: "CAL-2026-03"
|
|
19
|
+
site_id: opencactus
|
|
20
|
+
# ... other fields ...
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# Piano Editoriale — Marzo 2026
|
|
24
|
+
|
|
25
|
+
## Settimana 1 (1-7 Mar)
|
|
26
|
+
|
|
27
|
+
| Data | Titolo | Tipo | Status | Brief ID | Post ID | Canali |
|
|
28
|
+
|------|--------|------|--------|----------|---------|--------|
|
|
29
|
+
| Mar 4 | Article title here | post | planned | — | — | — |
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Frontmatter Fields
|
|
35
|
+
|
|
36
|
+
| Field | Type | Required | Default | Description |
|
|
37
|
+
|-------|------|----------|---------|-------------|
|
|
38
|
+
| `calendar_id` | `string` | **Yes** | -- | Unique calendar identifier. Format: `CAL-YYYY-MM` |
|
|
39
|
+
| `site_id` | `string` | **Yes** | -- | WordPress site identifier. Must match an existing `.content-state/{site_id}.config.md` |
|
|
40
|
+
| `period` | `string` | **Yes** | -- | Date range the calendar covers. Format: `YYYY-MM-DD..YYYY-MM-DD` (month boundaries) |
|
|
41
|
+
| `created` | `string` (ISO 8601) | **Yes** | -- | Date the calendar was first created |
|
|
42
|
+
| `last_updated` | `string` (ISO 8601) | **Yes** | -- | Auto-updated on each modification |
|
|
43
|
+
| `status` | `enum` | No | `active` | Calendar status: `active` \| `archived` |
|
|
44
|
+
| `goals.posts_target` | `integer` | **Yes** | -- | Total posts planned for the month |
|
|
45
|
+
| `goals.posts_published` | `integer` | No | `0` | Counter updated by SYNC step |
|
|
46
|
+
| `goals.focus_topics` | `string[]` | No | `[]` | Topic clusters to prioritize this month |
|
|
47
|
+
| `goals.seo_targets` | `object[]` | No | `[]` | Each object: `{keyword, target_position}` |
|
|
48
|
+
|
|
49
|
+
### `goals.seo_targets` object fields
|
|
50
|
+
|
|
51
|
+
| Field | Type | Required | Description |
|
|
52
|
+
|-------|------|----------|-------------|
|
|
53
|
+
| `keyword` | `string` | **Yes** | Target keyword or keyphrase |
|
|
54
|
+
| `target_position` | `string` | **Yes** | SERP target: `top-3`, `top-5`, `top-10`, `top-20` |
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Weekly Table Structure
|
|
59
|
+
|
|
60
|
+
The body contains one `## Settimana N (date range)` section per week of the month. Each section contains a single Markdown table with 7 columns:
|
|
61
|
+
|
|
62
|
+
| Column | Type | Description |
|
|
63
|
+
|--------|------|-------------|
|
|
64
|
+
| Data | `date` | Planned publication date. Format: `Mon DD` (e.g., `Mar 4`) |
|
|
65
|
+
| Titolo | `string` | Content title, or `[da assegnare]` if not yet defined |
|
|
66
|
+
| Tipo | `enum` | WordPress content type: `post` \| `page` \| `custom_type` |
|
|
67
|
+
| Status | `enum` | Entry lifecycle status: `planned` \| `draft` \| `ready` \| `scheduled` \| `published` |
|
|
68
|
+
| Brief ID | `string` | Reference to `.brief.md` file. Format: `BRF-YYYY-NNN`, or `—` if not yet created |
|
|
69
|
+
| Post ID | `integer` | WordPress post ID after creation, or `—` if not yet created |
|
|
70
|
+
| Canali | `string` | Comma-separated distribution channels (e.g., `linkedin, newsletter`), or `—` |
|
|
71
|
+
|
|
72
|
+
**Notes:**
|
|
73
|
+
- Each week section covers 7 calendar days
|
|
74
|
+
- The final week of the month may extend beyond 7 days to cover the remaining days (e.g., `Settimana 4 (22-31 Mar)`)
|
|
75
|
+
- Table headers must be repeated in every weekly section
|
|
76
|
+
- The `—` character (em dash, U+2014) is used as the null/empty marker
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Entry Status Lifecycle
|
|
81
|
+
|
|
82
|
+
Calendar entries progress through a linear five-stage lifecycle:
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
planned → draft → ready → scheduled → published
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
| Status | Description | Calendar state | Brief state |
|
|
89
|
+
|--------|-------------|----------------|-------------|
|
|
90
|
+
| `planned` | Slot reserved in the calendar. Title may be `[da assegnare]` | Entry exists in weekly table | No brief file yet |
|
|
91
|
+
| `draft` | Title assigned, brief created | Title is final | Brief in `pipeline-active/` with `status: draft` |
|
|
92
|
+
| `ready` | Brief content finalized, quality gates passed | No change | Brief in `pipeline-active/` with `status: ready` |
|
|
93
|
+
| `scheduled` | WordPress post created with future publication date | Post ID populated | Brief `target.status: future` |
|
|
94
|
+
| `published` | WordPress post is live, confirmed by SYNC step | Post ID present, status updated | Brief moves to `pipeline-archive/` |
|
|
95
|
+
|
|
96
|
+
**Transition rules:**
|
|
97
|
+
- `planned` -> `draft`: Requires a final title and Brief ID assignment
|
|
98
|
+
- `draft` -> `ready`: Requires brief quality gates to pass (see `gates` block in content-brief-schema)
|
|
99
|
+
- `ready` -> `scheduled`: Requires successful WordPress API call creating a post with `status: future`
|
|
100
|
+
- `scheduled` -> `published`: Confirmed by the SYNC step when WordPress reports `post_status: publish`
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Integration with Phase 1 (Content Pipeline)
|
|
105
|
+
|
|
106
|
+
The editorial calendar bridges directly to the content pipeline's brief system:
|
|
107
|
+
|
|
108
|
+
- Each calendar entry with a Brief ID references a file at `.content-state/pipeline-active/BRF-YYYY-NNN.brief.md`
|
|
109
|
+
- When the BRIEF step creates a new brief, it uses the site config defaults from `.content-state/{site_id}.config.md`
|
|
110
|
+
- The brief's `target.scheduled_date` is set from the calendar entry's **Data** column
|
|
111
|
+
- The brief's `distribution.channels` is set from the calendar entry's **Canali** column
|
|
112
|
+
- When `wp-content-pipeline` archives a brief (`status: published`), the SYNC step updates the calendar entry accordingly
|
|
113
|
+
|
|
114
|
+
### Data flow: Calendar -> Brief
|
|
115
|
+
|
|
116
|
+
| Calendar column | Brief field | Notes |
|
|
117
|
+
|-----------------|-------------|-------|
|
|
118
|
+
| Data | `target.scheduled_date` | Converted to ISO 8601 with site default publish time |
|
|
119
|
+
| Titolo | `content.title` | Exact match |
|
|
120
|
+
| Tipo | `target.content_type` | Direct mapping |
|
|
121
|
+
| Canali | `distribution.channels` | Comma-separated string parsed to array |
|
|
122
|
+
| (site_id from frontmatter) | `target.site_id` | Inherited from calendar |
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Integration with Phase 2 (Signals Intelligence)
|
|
127
|
+
|
|
128
|
+
The editorial calendar consumes signals intelligence data to inform content planning:
|
|
129
|
+
|
|
130
|
+
- The PLAN step can read `.content-state/signals-feed.md` to suggest topics for `[da assegnare]` entries
|
|
131
|
+
- Anomalies from the signals feed with action containing "content cluster opportunity" are prime candidates for planned entries
|
|
132
|
+
- The `goals.focus_topics` field can be informed by high-scoring signal patterns
|
|
133
|
+
|
|
134
|
+
### Signal-to-calendar workflow
|
|
135
|
+
|
|
136
|
+
1. SCAN step generates `.content-state/signals-feed.md` with scored anomalies
|
|
137
|
+
2. PLAN step reads the signals feed and identifies actionable opportunities
|
|
138
|
+
3. Opportunities map to `[da assegnare]` slots in the current or next month's calendar
|
|
139
|
+
4. When a topic is assigned, the entry title is updated and a `[da assegnare — topic da signals]` annotation may be used as an intermediate step
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Notes Section
|
|
144
|
+
|
|
145
|
+
The body may end with a `# Note` section containing free-form editorial notes.
|
|
146
|
+
|
|
147
|
+
Common uses:
|
|
148
|
+
- **Newsletter aggregation rules**: How posts are grouped for newsletter distribution (e.g., biweekly digest)
|
|
149
|
+
- **Distribution timing preferences**: When posts should be distributed on specific channels (e.g., LinkedIn at 09:00)
|
|
150
|
+
- **Topic dependencies on signals data**: Which `[da assegnare]` slots depend on future signals analysis
|
|
151
|
+
- **Cross-calendar references**: Links to related months or seasonal content plans
|
|
152
|
+
- **Team coordination notes**: Reviewer assignments, approval deadlines
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## File Naming Convention
|
|
157
|
+
|
|
158
|
+
Editorial calendar files follow this naming pattern:
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
{YYYY-MM}-editorial.state.md
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Examples:
|
|
165
|
+
- `2026-03-editorial.state.md`
|
|
166
|
+
- `2026-04-editorial.state.md`
|
|
167
|
+
|
|
168
|
+
Files are stored in:
|
|
169
|
+
- **Location**: `.content-state/` directory at the project root
|
|
170
|
+
- **One file per month per site**: The `site_id` is stored in the frontmatter, not the filename
|
|
171
|
+
- **Previous months**: Calendars for past months remain in `.content-state/` with `status: archived`
|
|
172
|
+
- **Gitignored**: Calendar files are site-specific instance data and should be listed in `.gitignore`
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Example Calendar
|
|
177
|
+
|
|
178
|
+
A complete `2026-03-editorial.state.md` for the opencactus site:
|
|
179
|
+
|
|
180
|
+
```markdown
|
|
181
|
+
---
|
|
182
|
+
calendar_id: "CAL-2026-03"
|
|
183
|
+
site_id: opencactus
|
|
184
|
+
period: "2026-03-01..2026-03-31"
|
|
185
|
+
created: "2026-02-28"
|
|
186
|
+
last_updated: "2026-03-02"
|
|
187
|
+
status: active
|
|
188
|
+
|
|
189
|
+
goals:
|
|
190
|
+
posts_target: 8
|
|
191
|
+
posts_published: 2
|
|
192
|
+
focus_topics: [cactus-water, sustainability, wellness]
|
|
193
|
+
seo_targets:
|
|
194
|
+
- keyword: "acqua di cactus"
|
|
195
|
+
target_position: top-5
|
|
196
|
+
- keyword: "bevanda zero calorie naturale"
|
|
197
|
+
target_position: top-10
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
# Piano Editoriale — Marzo 2026
|
|
201
|
+
|
|
202
|
+
## Settimana 1 (1-7 Mar)
|
|
203
|
+
|
|
204
|
+
| Data | Titolo | Tipo | Status | Brief ID | Post ID | Canali |
|
|
205
|
+
|------|--------|------|--------|----------|---------|--------|
|
|
206
|
+
| Mar 4 | Acqua di cactus: 5 benefici scientifici | post | published | BRF-2026-001 | 1234 | linkedin, newsletter |
|
|
207
|
+
| Mar 6 | Come il fico d'India diventa bevanda | post | published | BRF-2026-002 | 1235 | linkedin, twitter |
|
|
208
|
+
|
|
209
|
+
## Settimana 2 (8-14 Mar)
|
|
210
|
+
|
|
211
|
+
| Data | Titolo | Tipo | Status | Brief ID | Post ID | Canali |
|
|
212
|
+
|------|--------|------|--------|----------|---------|--------|
|
|
213
|
+
| Mar 11 | Zero calorie, tutto gusto: la scienza | post | ready | BRF-2026-003 | — | linkedin, newsletter |
|
|
214
|
+
| Mar 13 | Sicilia e sostenibilità: la filiera | post | draft | BRF-2026-004 | — | linkedin |
|
|
215
|
+
|
|
216
|
+
## Settimana 3 (15-21 Mar)
|
|
217
|
+
|
|
218
|
+
| Data | Titolo | Tipo | Status | Brief ID | Post ID | Canali |
|
|
219
|
+
|------|--------|------|--------|----------|---------|--------|
|
|
220
|
+
| Mar 18 | [da assegnare — topic da signals] | post | planned | — | — | — |
|
|
221
|
+
| Mar 20 | [da assegnare] | post | planned | — | — | — |
|
|
222
|
+
|
|
223
|
+
## Settimana 4 (22-31 Mar)
|
|
224
|
+
|
|
225
|
+
| Data | Titolo | Tipo | Status | Brief ID | Post ID | Canali |
|
|
226
|
+
|------|--------|------|--------|----------|---------|--------|
|
|
227
|
+
| Mar 25 | [da assegnare] | post | planned | — | — | — |
|
|
228
|
+
| Mar 27 | [da assegnare] | post | planned | — | — | — |
|
|
229
|
+
|
|
230
|
+
# Note
|
|
231
|
+
|
|
232
|
+
- Settimana 3-4: topic da definire basandosi su signals-feed.md del 15 marzo
|
|
233
|
+
- Newsletter quindicinale: raccoglie i 4 post della quindicina precedente
|
|
234
|
+
- LinkedIn: ogni post va distribuito il giorno stesso alle 09:00
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## Validation Rules
|
|
240
|
+
|
|
241
|
+
The following rules are enforced when reading and writing editorial calendar files:
|
|
242
|
+
|
|
243
|
+
### Format validations
|
|
244
|
+
|
|
245
|
+
| Rule | Description |
|
|
246
|
+
|------|-------------|
|
|
247
|
+
| `calendar_id` format | Must follow `CAL-YYYY-MM` pattern (e.g., `CAL-2026-03`) |
|
|
248
|
+
| `site_id` existence | Must match an existing `.content-state/{site_id}.config.md` file |
|
|
249
|
+
| `period` span | Must span exactly one calendar month (`YYYY-MM-DD..YYYY-MM-DD`) |
|
|
250
|
+
| Table columns | Each weekly table must have all 7 columns: Data, Titolo, Tipo, Status, Brief ID, Post ID, Canali |
|
|
251
|
+
|
|
252
|
+
### Field validations
|
|
253
|
+
|
|
254
|
+
| Rule | Description |
|
|
255
|
+
|------|-------------|
|
|
256
|
+
| `Status` values | Must be one of: `planned`, `draft`, `ready`, `scheduled`, `published` |
|
|
257
|
+
| `Brief ID` format | Must follow `BRF-YYYY-NNN` pattern when present (not `—`) |
|
|
258
|
+
| `Post ID` type | Must be a positive integer when present (not `—`) |
|
|
259
|
+
|
|
260
|
+
### Consistency validations
|
|
261
|
+
|
|
262
|
+
| Rule | Description |
|
|
263
|
+
|------|-------------|
|
|
264
|
+
| Published count | `goals.posts_published` must not exceed `goals.posts_target` |
|
|
265
|
+
| Scheduled requires Post ID | Entries with `status: scheduled` must have a Post ID (not `—`) |
|
|
266
|
+
| Published requires Post ID | Entries with `status: published` must have a Post ID (not `—`) |
|
|
267
|
+
| Draft requires Brief ID | Entries with `status: draft` or higher must have a Brief ID (not `—`) |
|
|
268
|
+
| Planned allows empty | Entries with `status: planned` may have `—` for Brief ID, Post ID, and Canali |
|