Skip to content

Commit a08da86

Browse files
authored
feat(wordpress): add category/tag CRUD tools, fix delete-status and dead-field bugs (#5360)
* feat(wordpress): add category/tag CRUD tools, fix delete-status and dead-field bugs - Add wordpress_{get,update,delete}_category and _tag tools for full taxonomy parity - Fix `deleted: data.deleted || true` always evaluating true across all 6 delete tools (posts/pages/media/comments/categories/tags) - Remove dead `force` param from delete_media (endpoint always force-deletes; param had zero effect) - Remove unwired `hideEmpty` block input - Normalize search_content perPage/page visibility to user-or-llm for consistency * fix(wordpress): use ?? instead of || for zero-valued numeric fields in delete_category/tag count and parent can legitimately be 0 (empty term, top-level category); || was dropping those values, same antipattern already fixed for `deleted` in this PR. Flagged independently by Greptile and Cursor Bugbot. * fix(wordpress): use ?? for zero-valued numeric fields across all delete tools Same || antipattern already fixed for category/tag delete tools was still present in delete_post/page/comment/media for id, author, featured_media, menu_order, parent, post — all legitimately 0 in common cases (no featured image, top-level page/comment). Found by a final independent validation pass. * fix(wordpress): don't drop categoryParent=0 (root-level category) in block param mapping Truthy check on params.categoryParent treated a resolved numeric 0 (root-level, no parent) as unset. Flagged by Cursor Bugbot on create_category/update_category. * fix(wordpress): don't clear category/tag description on update when field left blank description used !== undefined (numeric-field convention) instead of a truthy check (string-field convention used everywhere else in this codebase, e.g. update_post/update_page excerpt), so an untouched empty description field silently wiped existing text on every update. Flagged by Cursor Bugbot. * fix(wordpress): fix search type/subtype mislabeling, complete I/O exposure gaps - search_content.ts: type param was mislabeled with subtype's vocabulary (post/page/attachment); real WP type enum is post/term/post-format. Rewired the block's Content Type dropdown to map to subtype (which is what post/page/attachment actually filter), not type. - Widened subBlock conditions so params already read by tools.config.params are actually reachable in the UI: commentPostId for list_comments, categories/tags for list_posts, parent for list_pages. - Added missing subBlocks for tool params with no UI path: comment parent/authorName/authorEmail/authorUrl (create_comment), media description (upload_media), author filter (list_posts). - Extended the ?? / !== undefined fix (already applied to categoryParent) to the same class of param across the block: featuredMedia, page parent, menuOrder, and the new commentParent/listAuthor mappings. - Fixed featuredMedia/parent truthy-check inconsistency in create_post, update_post, create_page, update_page, create_category, create_comment body builders to match the !== undefined convention used elsewhere. Found by an independent final validation pass across 3 parallel agents. * fix(wordpress): keep searchType subBlock id to preserve saved-workflow compat The type/subtype fix should only change which API param the field feeds (subtype, not type) — renaming the subBlock id to searchSubtype broke already-saved workflows with a search content-type filter set, since the block would stop reading the old searchType key. Reverted the id rename, kept the underlying subtype mapping fix. Flagged by Cursor Bugbot. * fix(wordpress): remove invalid Attachment search subtype, fix listAuthor input type - Search Content's "Content Type" dropdown offered Attachment, which maps to subtype=attachment. WP core's WP_REST_Post_Search_Handler explicitly excludes attachment from valid subtypes (media isn't searchable via /search) — selecting it guaranteed a 400 rest_invalid_param. Removed the option; only Post/Page (the only valid subtypes) remain. - listAuthor was declared type: 'string' in the inputs catalog despite being Number()-coerced before use, inconsistent with every other ID-like field (postId, pageId, categoryId, commentParent, etc. are all 'number'). Found by an independent final pre-merge validation pass, requested before merge to be certain of full API alignment.
1 parent 7a31871 commit a08da86

21 files changed

Lines changed: 978 additions & 75 deletions

apps/sim/blocks/blocks/wordpress.ts

Lines changed: 248 additions & 35 deletions
Large diffs are not rendered by default.

apps/sim/tools/registry.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4163,14 +4163,18 @@ import {
41634163
wordpressCreatePageTool,
41644164
wordpressCreatePostTool,
41654165
wordpressCreateTagTool,
4166+
wordpressDeleteCategoryTool,
41664167
wordpressDeleteCommentTool,
41674168
wordpressDeleteMediaTool,
41684169
wordpressDeletePageTool,
41694170
wordpressDeletePostTool,
4171+
wordpressDeleteTagTool,
4172+
wordpressGetCategoryTool,
41704173
wordpressGetCurrentUserTool,
41714174
wordpressGetMediaTool,
41724175
wordpressGetPageTool,
41734176
wordpressGetPostTool,
4177+
wordpressGetTagTool,
41744178
wordpressGetUserTool,
41754179
wordpressListCategoriesTool,
41764180
wordpressListCommentsTool,
@@ -4180,9 +4184,11 @@ import {
41804184
wordpressListTagsTool,
41814185
wordpressListUsersTool,
41824186
wordpressSearchContentTool,
4187+
wordpressUpdateCategoryTool,
41834188
wordpressUpdateCommentTool,
41844189
wordpressUpdatePageTool,
41854190
wordpressUpdatePostTool,
4191+
wordpressUpdateTagTool,
41864192
wordpressUploadMediaTool,
41874193
} from '@/tools/wordpress'
41884194
import {
@@ -7490,8 +7496,14 @@ export const tools: Record<string, ToolConfig> = {
74907496
wordpress_delete_comment: wordpressDeleteCommentTool,
74917497
wordpress_create_category: wordpressCreateCategoryTool,
74927498
wordpress_list_categories: wordpressListCategoriesTool,
7499+
wordpress_get_category: wordpressGetCategoryTool,
7500+
wordpress_update_category: wordpressUpdateCategoryTool,
7501+
wordpress_delete_category: wordpressDeleteCategoryTool,
74937502
wordpress_create_tag: wordpressCreateTagTool,
74947503
wordpress_list_tags: wordpressListTagsTool,
7504+
wordpress_get_tag: wordpressGetTagTool,
7505+
wordpress_update_tag: wordpressUpdateTagTool,
7506+
wordpress_delete_tag: wordpressDeleteTagTool,
74957507
wordpress_get_current_user: wordpressGetCurrentUserTool,
74967508
wordpress_list_users: wordpressListUsersTool,
74977509
wordpress_get_user: wordpressGetUserTool,

apps/sim/tools/wordpress/create_category.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ export const createCategoryTool: ToolConfig<
6666
}
6767

6868
if (params.description) body.description = params.description
69-
if (params.parent) body.parent = params.parent
69+
if (params.parent !== undefined) body.parent = params.parent
7070
if (params.slug) body.slug = params.slug
7171

7272
return body

apps/sim/tools/wordpress/create_comment.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ export const createCommentTool: ToolConfig<
7878
content: params.content,
7979
}
8080

81-
if (params.parent) body.parent = params.parent
81+
if (params.parent !== undefined) body.parent = params.parent
8282
if (params.authorName) body.author_name = params.authorName
8383
if (params.authorEmail) body.author_email = params.authorEmail
8484
if (params.authorUrl) body.author_url = params.authorUrl

apps/sim/tools/wordpress/create_page.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,9 @@ export const createPageTool: ToolConfig<WordPressCreatePageParams, WordPressCrea
9090
if (params.status) body.status = params.status
9191
if (params.excerpt) body.excerpt = params.excerpt
9292
if (params.slug) body.slug = params.slug
93-
if (params.parent) body.parent = params.parent
94-
if (params.menuOrder) body.menu_order = params.menuOrder
95-
if (params.featuredMedia) body.featured_media = params.featuredMedia
93+
if (params.parent !== undefined) body.parent = params.parent
94+
if (params.menuOrder !== undefined) body.menu_order = params.menuOrder
95+
if (params.featuredMedia !== undefined) body.featured_media = params.featuredMedia
9696

9797
return body
9898
},

apps/sim/tools/wordpress/create_post.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ export const createPostTool: ToolConfig<WordPressCreatePostParams, WordPressCrea
9090
if (params.status) body.status = params.status
9191
if (params.excerpt) body.excerpt = params.excerpt
9292
if (params.slug) body.slug = params.slug
93-
if (params.featuredMedia) body.featured_media = params.featuredMedia
93+
if (params.featuredMedia !== undefined) body.featured_media = params.featuredMedia
9494

9595
if (params.categories) {
9696
body.categories = params.categories
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import type { ToolConfig } from '@/tools/types'
2+
import {
3+
WORDPRESS_COM_API_BASE,
4+
type WordPressDeleteCategoryParams,
5+
type WordPressDeleteCategoryResponse,
6+
} from '@/tools/wordpress/types'
7+
8+
export const deleteCategoryTool: ToolConfig<
9+
WordPressDeleteCategoryParams,
10+
WordPressDeleteCategoryResponse
11+
> = {
12+
id: 'wordpress_delete_category',
13+
name: 'WordPress Delete Category',
14+
description: 'Delete a category from WordPress.com',
15+
version: '1.0.0',
16+
17+
oauth: {
18+
required: true,
19+
provider: 'wordpress',
20+
requiredScopes: ['global'],
21+
},
22+
23+
params: {
24+
siteId: {
25+
type: 'string',
26+
required: true,
27+
visibility: 'user-or-llm',
28+
description: 'WordPress.com site ID or domain (e.g., 12345678 or mysite.wordpress.com)',
29+
},
30+
categoryId: {
31+
type: 'number',
32+
required: true,
33+
visibility: 'user-or-llm',
34+
description: 'The ID of the category to delete',
35+
},
36+
},
37+
38+
request: {
39+
url: (params) => {
40+
// Terms do not support trashing, so force=true is required to delete.
41+
return `${WORDPRESS_COM_API_BASE}/${params.siteId}/categories/${params.categoryId}?force=true`
42+
},
43+
method: 'DELETE',
44+
headers: (params) => ({
45+
'Content-Type': 'application/json',
46+
Authorization: `Bearer ${params.accessToken}`,
47+
}),
48+
},
49+
50+
transformResponse: async (response: Response) => {
51+
if (!response.ok) {
52+
const error = await response.json().catch(() => ({}))
53+
throw new Error(error.message || `WordPress API error: ${response.status}`)
54+
}
55+
56+
const data = await response.json()
57+
58+
return {
59+
success: true,
60+
output: {
61+
deleted: data.deleted ?? true,
62+
category: {
63+
id: data.id ?? data.previous?.id,
64+
count: data.count ?? data.previous?.count,
65+
description: data.description || data.previous?.description,
66+
link: data.link || data.previous?.link,
67+
name: data.name || data.previous?.name,
68+
slug: data.slug || data.previous?.slug,
69+
taxonomy: data.taxonomy || data.previous?.taxonomy,
70+
parent: data.parent ?? data.previous?.parent,
71+
},
72+
},
73+
}
74+
},
75+
76+
outputs: {
77+
deleted: {
78+
type: 'boolean',
79+
description: 'Whether the category was deleted',
80+
},
81+
category: {
82+
type: 'object',
83+
description: 'The deleted category',
84+
properties: {
85+
id: { type: 'number', description: 'Category ID' },
86+
count: { type: 'number', description: 'Number of posts in this category' },
87+
description: { type: 'string', description: 'Category description' },
88+
link: { type: 'string', description: 'Category archive URL' },
89+
name: { type: 'string', description: 'Category name' },
90+
slug: { type: 'string', description: 'Category slug' },
91+
taxonomy: { type: 'string', description: 'Taxonomy name' },
92+
parent: { type: 'number', description: 'Parent category ID' },
93+
},
94+
},
95+
},
96+
}

apps/sim/tools/wordpress/delete_comment.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,12 @@ export const deleteCommentTool: ToolConfig<
6464
return {
6565
success: true,
6666
output: {
67-
deleted: data.deleted || true,
67+
deleted: data.deleted ?? true,
6868
comment: {
69-
id: data.id || data.previous?.id,
70-
post: data.post || data.previous?.post,
71-
parent: data.parent || data.previous?.parent,
72-
author: data.author || data.previous?.author,
69+
id: data.id ?? data.previous?.id,
70+
post: data.post ?? data.previous?.post,
71+
parent: data.parent ?? data.previous?.parent,
72+
author: data.author ?? data.previous?.author,
7373
author_name: data.author_name || data.previous?.author_name,
7474
author_email: data.author_email || data.previous?.author_email,
7575
author_url: data.author_url || data.previous?.author_url,

apps/sim/tools/wordpress/delete_media.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,11 @@ export const deleteMediaTool: ToolConfig<WordPressDeleteMediaParams, WordPressDe
3131
visibility: 'user-or-llm',
3232
description: 'The ID of the media item to delete',
3333
},
34-
force: {
35-
type: 'boolean',
36-
required: false,
37-
visibility: 'user-only',
38-
description: 'Force delete (media has no trash, so deletion is permanent)',
39-
},
4034
},
4135

4236
request: {
4337
url: (params) => {
44-
// Media deletion requires force=true to actually delete
38+
// Media has no trash — deletion always requires force=true to take effect
4539
return `${WORDPRESS_COM_API_BASE}/${params.siteId}/media/${params.mediaId}?force=true`
4640
},
4741
method: 'DELETE',
@@ -62,9 +56,9 @@ export const deleteMediaTool: ToolConfig<WordPressDeleteMediaParams, WordPressDe
6256
return {
6357
success: true,
6458
output: {
65-
deleted: data.deleted || true,
59+
deleted: data.deleted ?? true,
6660
media: {
67-
id: data.id || data.previous?.id,
61+
id: data.id ?? data.previous?.id,
6862
date: data.date || data.previous?.date,
6963
slug: data.slug || data.previous?.slug,
7064
type: data.type || data.previous?.type,

apps/sim/tools/wordpress/delete_page.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@ export const deletePageTool: ToolConfig<WordPressDeletePageParams, WordPressDele
6161
return {
6262
success: true,
6363
output: {
64-
deleted: data.deleted || true,
64+
deleted: data.deleted ?? true,
6565
page: {
66-
id: data.id || data.previous?.id,
66+
id: data.id ?? data.previous?.id,
6767
date: data.date || data.previous?.date,
6868
modified: data.modified || data.previous?.modified,
6969
slug: data.slug || data.previous?.slug,
@@ -73,10 +73,10 @@ export const deletePageTool: ToolConfig<WordPressDeletePageParams, WordPressDele
7373
title: data.title || data.previous?.title,
7474
content: data.content || data.previous?.content,
7575
excerpt: data.excerpt || data.previous?.excerpt,
76-
author: data.author || data.previous?.author,
77-
featured_media: data.featured_media || data.previous?.featured_media,
78-
parent: data.parent || data.previous?.parent,
79-
menu_order: data.menu_order || data.previous?.menu_order,
76+
author: data.author ?? data.previous?.author,
77+
featured_media: data.featured_media ?? data.previous?.featured_media,
78+
parent: data.parent ?? data.previous?.parent,
79+
menu_order: data.menu_order ?? data.previous?.menu_order,
8080
},
8181
},
8282
}

0 commit comments

Comments
 (0)