maeve-cli 0.10.0 → 0.10.1

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 (3) hide show
  1. package/README.md +7 -3
  2. package/dist/index.js +3308 -41
  3. package/package.json +12 -11
package/dist/index.js CHANGED
@@ -1,4 +1,3108 @@
1
1
  #!/usr/bin/env node
2
+ import { createRequire as __maeveCreateRequire } from 'module'; const require = __maeveCreateRequire(import.meta.url);
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
10
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
11
+ }) : x)(function(x) {
12
+ if (typeof require !== "undefined") return require.apply(this, arguments);
13
+ throw Error('Dynamic require of "' + x + '" is not supported');
14
+ });
15
+ var __commonJS = (cb, mod) => function __require2() {
16
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
27
+ // If the importer is in node compatibility mode or this is not an ESM
28
+ // file that has been converted to a CommonJS file using a Babel-
29
+ // compatible transform (i.e. "__esModule" has not been set), then set
30
+ // "default" to the CommonJS "module.exports" for node compatibility.
31
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
32
+ mod
33
+ ));
34
+
35
+ // ../tool-contracts/dist/index.js
36
+ var require_dist = __commonJS({
37
+ "../tool-contracts/dist/index.js"(exports) {
38
+ "use strict";
39
+ var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
40
+ if (k2 === void 0) k2 = k;
41
+ var desc = Object.getOwnPropertyDescriptor(m, k);
42
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
43
+ desc = { enumerable: true, get: function() {
44
+ return m[k];
45
+ } };
46
+ }
47
+ Object.defineProperty(o, k2, desc);
48
+ }) : (function(o, m, k, k2) {
49
+ if (k2 === void 0) k2 = k;
50
+ o[k2] = m[k];
51
+ }));
52
+ var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? (function(o, v) {
53
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
54
+ }) : function(o, v) {
55
+ o["default"] = v;
56
+ });
57
+ var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() {
58
+ var ownKeys = function(o) {
59
+ ownKeys = Object.getOwnPropertyNames || function(o2) {
60
+ var ar = [];
61
+ for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
62
+ return ar;
63
+ };
64
+ return ownKeys(o);
65
+ };
66
+ return function(mod) {
67
+ if (mod && mod.__esModule) return mod;
68
+ var result = {};
69
+ if (mod != null) {
70
+ for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
71
+ }
72
+ __setModuleDefault(result, mod);
73
+ return result;
74
+ };
75
+ })();
76
+ Object.defineProperty(exports, "__esModule", { value: true });
77
+ exports.CONTENT_GET_COUNTS_CONTRACT = exports.CONTENT_GET_CONTRACT = exports.CONTENT_LIST_CONTRACT = exports.contentGetCountsMcpInputSchema = exports.contentGetMcpInputSchema = exports.contentGetInputSchema = exports.contentGetCountsInputSchema = exports.contentListAgentInputSchema = exports.contentListInputSchema = exports.contentListMcpInputSchema = exports.COMPOSER_PATCH_MEDIA_CONTRACT = exports.COMPOSER_PATCH_TAXONOMY_CONTRACT = exports.COMPOSER_PATCH_SCHEDULE_CONTRACT = exports.COMPOSER_PATCH_CAPTION_CONTRACT = exports.composerPatchOutputSchema = exports.composerPatchArtifactMetadataSchema = exports.composerPatchMediaArtifactMetadataSchema = exports.composerPatchTaxonomyArtifactMetadataSchema = exports.composerPatchScheduleArtifactMetadataSchema = exports.composerPatchCaptionArtifactMetadataSchema = exports.composerPatchMediaInputSchema = exports.composerPatchTaxonomyInputSchema = exports.composerPatchScheduleInputSchema = exports.composerPatchCaptionInputSchema = exports.MEDIA_SEARCH_CONTRACT = exports.mediaSearchOutputSchema = exports.mediaSearchInputSchema = exports.CALENDAR_SUGGEST_PUBLISH_TIMES_CONTRACT = exports.calendarSuggestPublishTimesOutputSchema = exports.calendarSuggestPublishTimesInputSchema = exports.CALENDAR_READ_RANGE_CONTRACT = exports.scheduledPostsListOutputSchema = exports.SCHEDULED_POSTS_PRESENTATION_NOTE_KINDS = exports.calendarReadRangeInputSchema = exports.CONTENT_FIND_RECENT_CONTRACT = exports.contentFindRecentOutputSchema = exports.contentFindRecentInputSchema = exports.MEMORY_REMEMBER_CONTRACT = exports.MEMORY_LIST_CONTRACT = exports.memoryRememberOutputSchema = exports.memoryListOutputSchema = exports.memoryRememberInputSchema = exports.memoryListInputSchema = exports.WORKSPACE_SUMMARY_CONTRACT = exports.workspaceSummaryOutputSchema = exports.workspaceSummaryInputSchema = exports.TIMEZONE_QUALIFIED_ISO8601_TIMESTAMP_ERROR = exports.TOOL_CAPABILITIES = exports.TOOL_WIRE_NAMES = exports.TOOL_OPERATION_IDS = void 0;
78
+ exports.analyticsPostsAggregateMcpInputSchema = exports.analyticsPostsMcpInputSchema = exports.analyticsIntegrationMcpInputSchema = exports.analyticsAggregateMcpInputSchema = exports.MEDIA_GET_USAGE_HISTORY_CONTRACT = exports.MEDIA_GET_CONTRACT = exports.MEDIA_LIST_LABELS_CONTRACT = exports.MEDIA_GET_FOLDER_PATH_CONTRACT = exports.MEDIA_GET_FOLDER_CONTRACT = exports.MEDIA_LIST_FOLDERS_CONTRACT = exports.MEDIA_LIST_CONTRACT = exports.mediaGetUsageHistoryAgentInputSchema = exports.mediaGetUsageHistoryInputSchema = exports.mediaGetInputSchema = exports.mediaListLabelsInputSchema = exports.mediaGetFolderPathInputSchema = exports.mediaGetFolderInputSchema = exports.mediaListFoldersInputSchema = exports.mediaListAgentInputSchema = exports.mediaListInputSchema = exports.mediaGetUsageHistoryMcpInputSchema = exports.mediaGetMcpInputSchema = exports.mediaListLabelsMcpInputSchema = exports.mediaGetFolderPathMcpInputSchema = exports.mediaGetFolderMcpInputSchema = exports.mediaListFoldersMcpInputSchema = exports.mediaListMcpInputSchema = exports.HASHTAG_GROUPS_LIST_CONTRACT = exports.CAMPAIGNS_LIST_CONTRACT = exports.TAXONOMY_LIST_CONTRACT = exports.INTEGRATIONS_GET_OPTIONS_CONTRACT = exports.INTEGRATIONS_GET_CAPABILITIES_CONTRACT = exports.INTEGRATIONS_LIST_CONTRACT = exports.hashtagGroupsListOutputSchema = exports.campaignsListOutputSchema = exports.taxonomyListOutputSchema = exports.integrationsListOutputSchema = exports.hashtagGroupsListMcpInputSchema = exports.hashtagGroupsListInputSchema = exports.campaignsListMcpInputSchema = exports.campaignsListInputSchema = exports.taxonomyListMcpInputSchema = exports.taxonomyListInputSchema = exports.integrationsGetOptionsMcpInputSchema = exports.integrationsGetOptionsInputSchema = exports.integrationsGetCapabilitiesMcpInputSchema = exports.integrationsGetCapabilitiesInputSchema = exports.INTEGRATION_OPTION_KEYS = exports.integrationsListMcpInputSchema = exports.integrationsListInputSchema = void 0;
79
+ exports.CONTENT_SCHEDULE_CONTRACT = exports.deleteContentOutputSchema = exports.deleteContentMcpInputSchema = exports.deleteContentInputSchema = exports.retryContentOutputSchema = exports.retryContentMcpInputSchema = exports.retryContentInputSchema = exports.restoreContentOutputSchema = exports.restoreContentMcpInputSchema = exports.restoreContentInputSchema = exports.archiveContentOutputSchema = exports.archiveContentMcpInputSchema = exports.archiveContentInputSchema = exports.publishNowOutputSchema = exports.publishNowMcpInputSchema = exports.publishNowInputSchema = exports.contentScheduleOutputSchema = exports.contentScheduleMcpInputSchema = exports.contentScheduleInputSchema = exports.CONTENT_UPDATE_NOTES_CONTRACT = exports.CONTENT_UPDATE_METADATA_CONTRACT = exports.updateContentNotesOutputSchema = exports.updateContentMetadataOutputSchema = exports.updateContentNotesMcpInputSchema = exports.updateContentNotesInputSchema = exports.updateContentMetadataMcpInputSchema = exports.updateContentMetadataInputSchema = exports.CONTENT_UPDATE_DRAFT_CONTRACT = exports.updateDraftContentOutputSchema = exports.updateDraftContentMcpInputSchema = exports.updateDraftContentInputSchema = exports.CONTENT_CREATE_DRAFT_CONTRACT = exports.createDraftContentOutputSchema = exports.createDraftContentMcpInputSchema = exports.createDraftContentInputSchema = exports.ANALYTICS_GET_POST_CONTRACT = exports.ANALYTICS_GET_POSTS_AGGREGATE_CONTRACT = exports.ANALYTICS_GET_POSTS_CONTRACT = exports.ANALYTICS_GET_DEMOGRAPHICS_CONTRACT = exports.ANALYTICS_GET_HEALTH_CONTRACT = exports.ANALYTICS_GET_AGGREGATE_CONTRACT = exports.ANALYTICS_GET_SUMMARY_CONTRACT = exports.postAnalyticsInputSchema = exports.analyticsPostsAgentInputSchema = exports.analyticsPostsInputSchema = exports.analyticsIntegrationInputSchema = exports.analyticsAggregateAgentInputSchema = exports.analyticsAggregateInputSchema = exports.postAnalyticsMcpInputSchema = exports.analyticsPostsAggregateInputSchema = void 0;
80
+ exports.TOOL_CONTRACTS = exports.CONTENT_SET_INTENDED_PUBLISH_TIME_CONTRACT = exports.contentSetIntendedPublishTimeOutputSchema = exports.contentSetIntendedPublishTimeMcpInputSchema = exports.contentSetIntendedPublishTimeInputSchema = exports.CONTENT_DELETE_CONTRACT = exports.CONTENT_RETRY_CONTRACT = exports.CONTENT_RESTORE_CONTRACT = exports.CONTENT_ARCHIVE_CONTRACT = exports.CONTENT_PUBLISH_NOW_CONTRACT = void 0;
81
+ exports.isTimezoneQualifiedIso8601Timestamp = isTimezoneQualifiedIso8601Timestamp;
82
+ var z9 = __importStar(__require("zod/v4"));
83
+ exports.TOOL_OPERATION_IDS = {
84
+ workspaceSummary: "workspace.summary",
85
+ memoryList: "memory.list",
86
+ memoryRemember: "memory.remember",
87
+ contentFindRecent: "content.find_recent",
88
+ calendarReadRange: "calendar.read_range",
89
+ calendarSuggestPublishTimes: "calendar.suggest_publish_times",
90
+ mediaSearch: "media.search",
91
+ composerPatchCaption: "composer.patch_caption",
92
+ composerPatchSchedule: "composer.patch_schedule",
93
+ composerPatchTaxonomy: "composer.patch_taxonomy",
94
+ composerPatchMedia: "composer.patch_media",
95
+ contentList: "content.list",
96
+ contentGet: "content.get",
97
+ contentGetCounts: "content.get_counts",
98
+ integrationsList: "integrations.list",
99
+ integrationsGetCapabilities: "integrations.get_capabilities",
100
+ integrationsGetOptions: "integrations.get_options",
101
+ taxonomyList: "taxonomy.list",
102
+ campaignsList: "campaigns.list",
103
+ hashtagGroupsList: "hashtag_groups.list",
104
+ contentCreateDraft: "content.create_draft",
105
+ contentUpdateDraft: "content.update_draft",
106
+ contentUpdateMetadata: "content.update_metadata",
107
+ contentUpdateNotes: "content.update_notes",
108
+ contentSchedule: "content.schedule",
109
+ contentPublishNow: "content.publish_now",
110
+ contentArchive: "content.archive",
111
+ contentRestore: "content.restore",
112
+ contentRetry: "content.retry",
113
+ contentDelete: "content.delete",
114
+ contentSetIntendedPublishTime: "content.set_intended_publish_time",
115
+ mediaList: "media.list",
116
+ mediaListFolders: "media.list_folders",
117
+ mediaGetFolder: "media.get_folder",
118
+ mediaGetFolderPath: "media.get_folder_path",
119
+ mediaListLabels: "media.list_labels",
120
+ mediaGet: "media.get",
121
+ mediaGetUsageHistory: "media.get_usage_history",
122
+ analyticsGetSummary: "analytics.get_summary",
123
+ analyticsGetAggregate: "analytics.get_aggregate",
124
+ analyticsGetHealth: "analytics.get_health",
125
+ analyticsGetPosts: "analytics.get_posts",
126
+ analyticsGetPostsAggregate: "analytics.get_posts_aggregate",
127
+ analyticsGetPost: "analytics.get_post",
128
+ analyticsGetDemographics: "analytics.get_demographics"
129
+ };
130
+ exports.TOOL_WIRE_NAMES = {
131
+ workspaceSummary: {
132
+ agent: exports.TOOL_OPERATION_IDS.workspaceSummary
133
+ },
134
+ memoryList: {
135
+ agent: exports.TOOL_OPERATION_IDS.memoryList
136
+ },
137
+ memoryRemember: {
138
+ agent: exports.TOOL_OPERATION_IDS.memoryRemember
139
+ },
140
+ contentFindRecent: {
141
+ agent: exports.TOOL_OPERATION_IDS.contentFindRecent
142
+ },
143
+ calendarReadRange: {
144
+ agent: exports.TOOL_OPERATION_IDS.calendarReadRange
145
+ },
146
+ calendarSuggestPublishTimes: {
147
+ agent: exports.TOOL_OPERATION_IDS.calendarSuggestPublishTimes
148
+ },
149
+ mediaSearch: {
150
+ agent: exports.TOOL_OPERATION_IDS.mediaSearch
151
+ },
152
+ composerPatchCaption: {
153
+ agent: exports.TOOL_OPERATION_IDS.composerPatchCaption
154
+ },
155
+ composerPatchSchedule: {
156
+ agent: exports.TOOL_OPERATION_IDS.composerPatchSchedule
157
+ },
158
+ composerPatchTaxonomy: {
159
+ agent: exports.TOOL_OPERATION_IDS.composerPatchTaxonomy
160
+ },
161
+ composerPatchMedia: {
162
+ agent: exports.TOOL_OPERATION_IDS.composerPatchMedia
163
+ },
164
+ contentList: {
165
+ agent: exports.TOOL_OPERATION_IDS.contentList,
166
+ mcp: "list_content"
167
+ },
168
+ contentGet: {
169
+ agent: exports.TOOL_OPERATION_IDS.contentGet,
170
+ mcp: "get_content"
171
+ },
172
+ contentGetCounts: {
173
+ agent: exports.TOOL_OPERATION_IDS.contentGetCounts,
174
+ mcp: "get_content_counts"
175
+ },
176
+ integrationsList: {
177
+ agent: exports.TOOL_OPERATION_IDS.integrationsList,
178
+ mcp: "list_integrations"
179
+ },
180
+ integrationsGetCapabilities: {
181
+ agent: exports.TOOL_OPERATION_IDS.integrationsGetCapabilities,
182
+ mcp: "get_integration_capabilities"
183
+ },
184
+ integrationsGetOptions: {
185
+ agent: exports.TOOL_OPERATION_IDS.integrationsGetOptions,
186
+ mcp: "get_integration_options"
187
+ },
188
+ taxonomyList: {
189
+ agent: exports.TOOL_OPERATION_IDS.taxonomyList,
190
+ mcp: "list_taxonomy"
191
+ },
192
+ campaignsList: {
193
+ agent: exports.TOOL_OPERATION_IDS.campaignsList,
194
+ mcp: "list_campaigns"
195
+ },
196
+ hashtagGroupsList: {
197
+ agent: exports.TOOL_OPERATION_IDS.hashtagGroupsList,
198
+ mcp: "list_hashtag_groups"
199
+ },
200
+ contentCreateDraft: {
201
+ agent: exports.TOOL_OPERATION_IDS.contentCreateDraft,
202
+ mcp: "create_draft_content"
203
+ },
204
+ contentUpdateDraft: {
205
+ agent: exports.TOOL_OPERATION_IDS.contentUpdateDraft,
206
+ mcp: "update_content"
207
+ },
208
+ contentUpdateMetadata: {
209
+ agent: exports.TOOL_OPERATION_IDS.contentUpdateMetadata,
210
+ mcp: "update_content_metadata"
211
+ },
212
+ contentUpdateNotes: {
213
+ agent: exports.TOOL_OPERATION_IDS.contentUpdateNotes,
214
+ mcp: "update_content_notes"
215
+ },
216
+ contentSchedule: {
217
+ agent: exports.TOOL_OPERATION_IDS.contentSchedule,
218
+ mcp: "schedule_content"
219
+ },
220
+ contentPublishNow: {
221
+ agent: exports.TOOL_OPERATION_IDS.contentPublishNow,
222
+ mcp: "publish_now"
223
+ },
224
+ contentArchive: {
225
+ agent: exports.TOOL_OPERATION_IDS.contentArchive,
226
+ mcp: "archive_content"
227
+ },
228
+ contentRestore: {
229
+ agent: exports.TOOL_OPERATION_IDS.contentRestore,
230
+ mcp: "restore_content"
231
+ },
232
+ contentRetry: {
233
+ agent: exports.TOOL_OPERATION_IDS.contentRetry,
234
+ mcp: "retry_content"
235
+ },
236
+ contentDelete: {
237
+ agent: exports.TOOL_OPERATION_IDS.contentDelete,
238
+ mcp: "delete_content"
239
+ },
240
+ contentSetIntendedPublishTime: {
241
+ agent: exports.TOOL_OPERATION_IDS.contentSetIntendedPublishTime,
242
+ mcp: "set_intended_publish_time"
243
+ },
244
+ mediaList: {
245
+ agent: exports.TOOL_OPERATION_IDS.mediaList,
246
+ mcp: "list_media"
247
+ },
248
+ mediaListFolders: {
249
+ agent: exports.TOOL_OPERATION_IDS.mediaListFolders,
250
+ mcp: "list_media_folders"
251
+ },
252
+ mediaGetFolder: {
253
+ agent: exports.TOOL_OPERATION_IDS.mediaGetFolder,
254
+ mcp: "get_media_folder"
255
+ },
256
+ mediaGetFolderPath: {
257
+ agent: exports.TOOL_OPERATION_IDS.mediaGetFolderPath,
258
+ mcp: "get_media_folder_path"
259
+ },
260
+ mediaListLabels: {
261
+ agent: exports.TOOL_OPERATION_IDS.mediaListLabels,
262
+ mcp: "list_media_labels"
263
+ },
264
+ mediaGet: {
265
+ agent: exports.TOOL_OPERATION_IDS.mediaGet,
266
+ mcp: "get_media"
267
+ },
268
+ mediaGetUsageHistory: {
269
+ agent: exports.TOOL_OPERATION_IDS.mediaGetUsageHistory,
270
+ mcp: "get_media_usage_history"
271
+ },
272
+ analyticsGetSummary: {
273
+ agent: exports.TOOL_OPERATION_IDS.analyticsGetSummary,
274
+ mcp: "get_analytics_summary"
275
+ },
276
+ analyticsGetAggregate: {
277
+ agent: exports.TOOL_OPERATION_IDS.analyticsGetAggregate,
278
+ mcp: "get_analytics_aggregate"
279
+ },
280
+ analyticsGetHealth: {
281
+ agent: exports.TOOL_OPERATION_IDS.analyticsGetHealth,
282
+ mcp: "get_analytics_health"
283
+ },
284
+ analyticsGetPosts: {
285
+ agent: exports.TOOL_OPERATION_IDS.analyticsGetPosts,
286
+ mcp: "get_analytics_posts"
287
+ },
288
+ analyticsGetPostsAggregate: {
289
+ agent: exports.TOOL_OPERATION_IDS.analyticsGetPostsAggregate,
290
+ mcp: "get_analytics_posts_aggregate"
291
+ },
292
+ analyticsGetPost: {
293
+ agent: exports.TOOL_OPERATION_IDS.analyticsGetPost,
294
+ mcp: "get_post_analytics"
295
+ },
296
+ analyticsGetDemographics: {
297
+ agent: exports.TOOL_OPERATION_IDS.analyticsGetDemographics,
298
+ mcp: "get_analytics_demographics"
299
+ }
300
+ };
301
+ exports.TOOL_CAPABILITIES = {
302
+ workspaceRead: "workspace.read",
303
+ workspaceUpdate: "workspace.update",
304
+ contentDraftCreate: "content.draft.create",
305
+ contentDraftUpdate: "content.draft.update",
306
+ contentDraftArchive: "content.draft.archive",
307
+ contentDraftRestore: "content.draft.restore",
308
+ contentDraftDelete: "content.draft.delete",
309
+ contentSchedule: "content.schedule",
310
+ contentPublishNow: "content.publish_now",
311
+ contentRetryPublish: "content.retry_publish",
312
+ contentReviewSetIntendedPublishTime: "content.review.set_intended_publish_time",
313
+ mediaRead: "media.read",
314
+ analyticsRead: "analytics.read",
315
+ integrationsRead: "integrations.read"
316
+ };
317
+ function defineToolContract(contract) {
318
+ return contract;
319
+ }
320
+ var mcpReadAnnotations = {
321
+ readOnlyHint: true,
322
+ destructiveHint: false,
323
+ idempotentHint: true,
324
+ openWorldHint: false
325
+ };
326
+ var agentMemoryKindSchema = z9.string().trim().min(1).max(120);
327
+ var boundedStringRecordSchema = z9.record(z9.string(), z9.unknown());
328
+ var mcpStructuredContentOutputSchema = z9.record(z9.string(), z9.unknown());
329
+ exports.TIMEZONE_QUALIFIED_ISO8601_TIMESTAMP_ERROR = "must be a timezone-qualified ISO 8601 timestamp (for example 2026-05-01T10:30:00.000Z)";
330
+ var TIMEZONE_QUALIFIED_ISO8601_TIMESTAMP_REGEX = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,3}))?(Z|([+-])(\d{2}):(\d{2}))$/;
331
+ function isTimezoneQualifiedIso8601Timestamp(value) {
332
+ if (typeof value !== "string")
333
+ return false;
334
+ const match = TIMEZONE_QUALIFIED_ISO8601_TIMESTAMP_REGEX.exec(value);
335
+ if (!match)
336
+ return false;
337
+ const [, yearRaw, monthRaw, dayRaw, hourRaw, minuteRaw, secondRaw, millisecondRaw, zone, sign, zoneHourRaw, zoneMinuteRaw] = match;
338
+ const year = Number.parseInt(yearRaw, 10);
339
+ const month = Number.parseInt(monthRaw, 10);
340
+ const day = Number.parseInt(dayRaw, 10);
341
+ const hour = Number.parseInt(hourRaw, 10);
342
+ const minute = Number.parseInt(minuteRaw, 10);
343
+ const second = Number.parseInt(secondRaw, 10);
344
+ const millisecond = millisecondRaw ? Number.parseInt(millisecondRaw.padEnd(3, "0"), 10) : 0;
345
+ const zoneHour = zone === "Z" ? 0 : Number.parseInt(zoneHourRaw, 10);
346
+ const zoneMinute = zone === "Z" ? 0 : Number.parseInt(zoneMinuteRaw, 10);
347
+ if (month < 1 || month > 12 || day < 1 || day > 31 || hour > 23 || minute > 59 || second > 59 || zoneHour > 23 || zoneMinute > 59) {
348
+ return false;
349
+ }
350
+ const offsetMinutes = zone === "Z" ? 0 : (zoneHour * 60 + zoneMinute) * (sign === "+" ? 1 : -1);
351
+ const utcTime = Date.UTC(year, month - 1, day, hour, minute, second, millisecond) - offsetMinutes * 6e4;
352
+ if (!Number.isFinite(utcTime))
353
+ return false;
354
+ const localizedTime = new Date(utcTime + offsetMinutes * 6e4);
355
+ return localizedTime.getUTCFullYear() === year && localizedTime.getUTCMonth() + 1 === month && localizedTime.getUTCDate() === day && localizedTime.getUTCHours() === hour && localizedTime.getUTCMinutes() === minute && localizedTime.getUTCSeconds() === second && localizedTime.getUTCMilliseconds() === millisecond;
356
+ }
357
+ var timezoneQualifiedTimestampSchema = z9.string().refine(isTimezoneQualifiedIso8601Timestamp, {
358
+ message: `scheduledAt ${exports.TIMEZONE_QUALIFIED_ISO8601_TIMESTAMP_ERROR}`
359
+ }).describe("Timezone-qualified ISO-8601 intended publish time.");
360
+ exports.workspaceSummaryInputSchema = z9.object({}).strict();
361
+ exports.workspaceSummaryOutputSchema = z9.object({
362
+ ok: z9.literal(true),
363
+ renderHint: z9.literal("workspace_summary"),
364
+ workspace: boundedStringRecordSchema.nullable(),
365
+ organization: boundedStringRecordSchema.nullable(),
366
+ channels: z9.array(boundedStringRecordSchema)
367
+ }).strict();
368
+ exports.WORKSPACE_SUMMARY_CONTRACT = defineToolContract({
369
+ canonicalName: exports.TOOL_OPERATION_IDS.workspaceSummary,
370
+ wireNames: exports.TOOL_WIRE_NAMES.workspaceSummary,
371
+ description: "Summarize the current workspace identity, connected channels, and active plan context.",
372
+ inputSchema: exports.workspaceSummaryInputSchema,
373
+ outputSchema: exports.workspaceSummaryOutputSchema,
374
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.workspaceRead],
375
+ confirmation: { required: false },
376
+ idempotency: { required: false },
377
+ surfaces: {
378
+ agent: {
379
+ name: exports.TOOL_WIRE_NAMES.workspaceSummary.agent,
380
+ description: "Summarize the current workspace identity, connected channels, and active plan context.",
381
+ access: "read",
382
+ gated: false,
383
+ safeInputSummary: () => "current workspace summary"
384
+ }
385
+ }
386
+ });
387
+ exports.memoryListInputSchema = z9.object({
388
+ kind: agentMemoryKindSchema.optional(),
389
+ limit: z9.number().int().min(1).max(20).default(10)
390
+ }).strict();
391
+ exports.memoryRememberInputSchema = z9.object({
392
+ kind: agentMemoryKindSchema,
393
+ content: z9.string().trim().min(1).max(4e3),
394
+ confidence: z9.number().min(0).max(1).optional()
395
+ }).strict();
396
+ var memoryItemSchema = z9.object({
397
+ id: z9.string(),
398
+ kind: z9.string(),
399
+ content: z9.string(),
400
+ source: z9.string(),
401
+ confidence: z9.number().nullable(),
402
+ createdAt: z9.string(),
403
+ updatedAt: z9.string()
404
+ }).strict();
405
+ exports.memoryListOutputSchema = z9.object({
406
+ ok: z9.literal(true),
407
+ renderHint: z9.literal("agent_memory_list"),
408
+ items: z9.array(memoryItemSchema)
409
+ }).strict();
410
+ exports.memoryRememberOutputSchema = z9.object({
411
+ ok: z9.literal(true),
412
+ renderHint: z9.literal("agent_memory"),
413
+ memory: memoryItemSchema
414
+ }).strict();
415
+ exports.MEMORY_LIST_CONTRACT = defineToolContract({
416
+ canonicalName: exports.TOOL_OPERATION_IDS.memoryList,
417
+ wireNames: exports.TOOL_WIRE_NAMES.memoryList,
418
+ description: "List active durable workspace memory that may guide future agent turns.",
419
+ inputSchema: exports.memoryListInputSchema,
420
+ outputSchema: exports.memoryListOutputSchema,
421
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.workspaceRead],
422
+ confirmation: { required: false },
423
+ idempotency: { required: false },
424
+ surfaces: {
425
+ agent: {
426
+ name: exports.TOOL_WIRE_NAMES.memoryList.agent,
427
+ description: "List active durable workspace memory that may guide future agent turns.",
428
+ access: "read",
429
+ gated: false,
430
+ safeInputSummary: (input) => `kind=${input.kind ?? "any"} limit=${input.limit}`
431
+ }
432
+ }
433
+ });
434
+ exports.MEMORY_REMEMBER_CONTRACT = defineToolContract({
435
+ canonicalName: exports.TOOL_OPERATION_IDS.memoryRemember,
436
+ wireNames: exports.TOOL_WIRE_NAMES.memoryRemember,
437
+ description: "Store a durable workspace preference, brand rule, or factual context explicitly provided by the user.",
438
+ inputSchema: exports.memoryRememberInputSchema,
439
+ outputSchema: exports.memoryRememberOutputSchema,
440
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.workspaceUpdate],
441
+ confirmation: { required: false },
442
+ idempotency: { required: true },
443
+ surfaces: {
444
+ agent: {
445
+ name: exports.TOOL_WIRE_NAMES.memoryRemember.agent,
446
+ description: "Store a durable workspace preference, brand rule, or factual context explicitly provided by the user.",
447
+ access: "write",
448
+ gated: false,
449
+ safeInputSummary: (input) => `kind=${input.kind} contentLength=${input.content.length}`
450
+ }
451
+ }
452
+ });
453
+ exports.contentFindRecentInputSchema = z9.object({
454
+ status: z9.enum(["draft", "scheduled", "sent", "failed"]).optional(),
455
+ search: z9.string().trim().min(1).max(120).optional(),
456
+ limit: z9.number().int().min(1).max(20).default(8)
457
+ }).strict();
458
+ exports.contentFindRecentOutputSchema = z9.object({
459
+ ok: z9.literal(true),
460
+ renderHint: z9.literal("content_list"),
461
+ items: z9.array(boundedStringRecordSchema)
462
+ }).strict();
463
+ exports.CONTENT_FIND_RECENT_CONTRACT = defineToolContract({
464
+ canonicalName: exports.TOOL_OPERATION_IDS.contentFindRecent,
465
+ wireNames: exports.TOOL_WIRE_NAMES.contentFindRecent,
466
+ description: "Find recent draft, scheduled, published, or failed content in the current workspace.",
467
+ inputSchema: exports.contentFindRecentInputSchema,
468
+ outputSchema: exports.contentFindRecentOutputSchema,
469
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.workspaceRead],
470
+ confirmation: { required: false },
471
+ idempotency: { required: false },
472
+ surfaces: {
473
+ agent: {
474
+ name: exports.TOOL_WIRE_NAMES.contentFindRecent.agent,
475
+ description: "Find recent draft, scheduled, published, or failed content in the current workspace.",
476
+ access: "read",
477
+ gated: false,
478
+ safeInputSummary: (input) => `status=${input.status ?? "any"} limit=${input.limit}`
479
+ }
480
+ }
481
+ });
482
+ var calendarReadStatuses = ["draft", "pending_approval", "scheduled", "sent", "failed"];
483
+ var CALENDAR_READ_RANGE_MAX_DAYS = 370;
484
+ var DAY_MS = 24 * 60 * 60 * 1e3;
485
+ exports.calendarReadRangeInputSchema = z9.object({
486
+ startDate: z9.string().refine(isTimezoneQualifiedIso8601Timestamp, {
487
+ message: "startDate must be a timezone-qualified ISO 8601 timestamp."
488
+ }),
489
+ endDate: z9.string().refine(isTimezoneQualifiedIso8601Timestamp, {
490
+ message: "endDate must be a timezone-qualified ISO 8601 timestamp."
491
+ }),
492
+ statuses: z9.array(z9.enum(calendarReadStatuses)).min(1).max(calendarReadStatuses.length).optional(),
493
+ platforms: z9.array(z9.string().trim().min(1).max(40)).min(1).max(20).optional(),
494
+ integrationId: z9.string().uuid().optional(),
495
+ campaignId: z9.string().uuid().optional(),
496
+ limit: z9.number().int().min(1).max(100).default(50)
497
+ }).strict().superRefine((input, ctx) => {
498
+ const start = Date.parse(input.startDate);
499
+ const end = Date.parse(input.endDate);
500
+ if (!Number.isFinite(start) || !Number.isFinite(end))
501
+ return;
502
+ if (end < start) {
503
+ ctx.addIssue({
504
+ code: "custom",
505
+ path: ["endDate"],
506
+ message: "endDate must be on or after startDate."
507
+ });
508
+ return;
509
+ }
510
+ if ((end - start) / DAY_MS > CALENDAR_READ_RANGE_MAX_DAYS) {
511
+ ctx.addIssue({
512
+ code: "custom",
513
+ path: ["endDate"],
514
+ message: `Date range must be within ${CALENDAR_READ_RANGE_MAX_DAYS} days.`
515
+ });
516
+ }
517
+ });
518
+ exports.SCHEDULED_POSTS_PRESENTATION_NOTE_KINDS = [
519
+ "account_reauth_required",
520
+ "account_auth_incomplete",
521
+ "account_disabled"
522
+ ];
523
+ var scheduledPostListItemSchema = z9.object({
524
+ contentId: z9.string(),
525
+ postId: z9.string().nullable(),
526
+ groupId: z9.string().nullable(),
527
+ title: z9.string().nullable(),
528
+ captionSummary: z9.string().nullable(),
529
+ status: z9.string(),
530
+ workflowStatus: z9.string().nullable(),
531
+ scheduledAt: z9.string().nullable(),
532
+ sentAt: z9.string().nullable(),
533
+ calendarAt: z9.string().nullable(),
534
+ platform: z9.string().nullable(),
535
+ integrationId: z9.string().nullable(),
536
+ accountLabel: z9.string().nullable(),
537
+ actionRefs: z9.object({
538
+ openContent: z9.boolean()
539
+ }).strict()
540
+ }).strict();
541
+ var scheduledPostsPresentationSchema = z9.object({
542
+ contract: z9.literal("scheduled_posts_list_v1"),
543
+ notes: z9.array(z9.object({
544
+ kind: z9.enum(exports.SCHEDULED_POSTS_PRESENTATION_NOTE_KINDS),
545
+ severity: z9.literal("warning"),
546
+ message: z9.string(),
547
+ integrationId: z9.string().nullable().optional(),
548
+ platform: z9.string().nullable().optional(),
549
+ accountLabel: z9.string().nullable().optional()
550
+ }).strict()),
551
+ assistantNotePolicy: z9.object({
552
+ allowEmpty: z9.boolean(),
553
+ forbiddenFields: z9.array(z9.string()),
554
+ allowedTopics: z9.array(z9.string())
555
+ }).strict()
556
+ }).strict();
557
+ exports.scheduledPostsListOutputSchema = z9.object({
558
+ ok: z9.literal(true),
559
+ renderHint: z9.literal("scheduled_posts_list"),
560
+ timezone: z9.string(),
561
+ range: z9.object({
562
+ startDate: z9.string(),
563
+ endDate: z9.string()
564
+ }).strict(),
565
+ items: z9.array(scheduledPostListItemSchema),
566
+ presentation: scheduledPostsPresentationSchema,
567
+ assistantGuidance: z9.string().optional()
568
+ }).strict();
569
+ exports.CALENDAR_READ_RANGE_CONTRACT = defineToolContract({
570
+ canonicalName: exports.TOOL_OPERATION_IDS.calendarReadRange,
571
+ wireNames: exports.TOOL_WIRE_NAMES.calendarReadRange,
572
+ description: "Read scheduled, draft, sent, or failed calendar content in the current workspace for a date range.",
573
+ inputSchema: exports.calendarReadRangeInputSchema,
574
+ outputSchema: exports.scheduledPostsListOutputSchema,
575
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.workspaceRead],
576
+ confirmation: { required: false },
577
+ idempotency: { required: false },
578
+ surfaces: {
579
+ agent: {
580
+ name: exports.TOOL_WIRE_NAMES.calendarReadRange.agent,
581
+ description: "Read scheduled, draft, sent, or failed calendar content in the current workspace for a date range.",
582
+ access: "read",
583
+ gated: false,
584
+ safeInputSummary: (input) => [
585
+ `range=${input.startDate}..${input.endDate}`,
586
+ `statuses=${input.statuses?.join(",") ?? "any"}`,
587
+ `platforms=${input.platforms?.join(",") ?? "any"}`,
588
+ `limit=${input.limit}`
589
+ ].join(" ")
590
+ }
591
+ }
592
+ });
593
+ var PUBLISH_TIME_SUGGESTIONS_MAX_COARSE_DAYS = 32;
594
+ var localWindowTimeSchema = z9.string().regex(/^([01]\d|2[0-3]):([0-5]\d)$/, "must be HH:mm 24-hour time.");
595
+ exports.calendarSuggestPublishTimesInputSchema = z9.object({
596
+ startDate: z9.string().refine(isTimezoneQualifiedIso8601Timestamp, {
597
+ message: "startDate must be a timezone-qualified ISO 8601 timestamp."
598
+ }),
599
+ endDate: z9.string().refine(isTimezoneQualifiedIso8601Timestamp, {
600
+ message: "endDate must be a timezone-qualified ISO 8601 timestamp."
601
+ }),
602
+ platforms: z9.array(z9.string().trim().min(1).max(40)).min(1).max(20).optional(),
603
+ integrationId: z9.string().uuid().optional(),
604
+ campaignId: z9.string().uuid().optional(),
605
+ limit: z9.number().int().min(1).max(10).default(5),
606
+ candidateStepMinutes: z9.union([z9.literal(30), z9.literal(60), z9.literal(120)]).default(60),
607
+ minGapMinutes: z9.number().int().min(15).max(720).default(120),
608
+ localWindow: z9.object({ start: localWindowTimeSchema, end: localWindowTimeSchema }).strict().optional()
609
+ }).strict().superRefine((input, ctx) => {
610
+ const start = Date.parse(input.startDate);
611
+ const end = Date.parse(input.endDate);
612
+ if (!Number.isFinite(start) || !Number.isFinite(end))
613
+ return;
614
+ if (end < start) {
615
+ ctx.addIssue({ code: "custom", path: ["endDate"], message: "endDate must be on or after startDate." });
616
+ return;
617
+ }
618
+ if ((end - start) / DAY_MS > PUBLISH_TIME_SUGGESTIONS_MAX_COARSE_DAYS) {
619
+ ctx.addIssue({
620
+ code: "custom",
621
+ path: ["endDate"],
622
+ message: "Date range is too large for publish-time suggestions."
623
+ });
624
+ }
625
+ if (input.localWindow) {
626
+ const [sh, sm] = input.localWindow.start.split(":").map(Number);
627
+ const [eh, em] = input.localWindow.end.split(":").map(Number);
628
+ if (eh * 60 + em < sh * 60 + sm) {
629
+ ctx.addIssue({
630
+ code: "custom",
631
+ path: ["localWindow", "end"],
632
+ message: "localWindow.end must be on or after localWindow.start."
633
+ });
634
+ }
635
+ }
636
+ });
637
+ var publishTimeCandidateSchema = z9.object({
638
+ scheduledAt: z9.string(),
639
+ timezone: z9.string(),
640
+ score: z9.number(),
641
+ confidence: z9.enum(["high", "medium", "low"]),
642
+ reason: z9.string(),
643
+ density: z9.object({
644
+ sameDayHard: z9.number().int(),
645
+ sameDaySoft: z9.number().int(),
646
+ nearbyHard: z9.number().int(),
647
+ nearbySoft: z9.number().int()
648
+ }).strict(),
649
+ nearestItems: z9.array(z9.object({
650
+ title: z9.string().nullable(),
651
+ status: z9.string(),
652
+ platform: z9.string().nullable(),
653
+ calendarAt: z9.string(),
654
+ minutesAway: z9.number().int()
655
+ }).strict())
656
+ }).strict();
657
+ exports.calendarSuggestPublishTimesOutputSchema = z9.object({
658
+ ok: z9.literal(true),
659
+ renderHint: z9.literal("publish_time_suggestions"),
660
+ timezone: z9.string(),
661
+ range: z9.object({ startDate: z9.string(), endDate: z9.string() }).strict(),
662
+ candidates: z9.array(publishTimeCandidateSchema),
663
+ rejectedCount: z9.number().int(),
664
+ presentation: z9.object({
665
+ contract: z9.literal("publish_time_suggestions_v1"),
666
+ renderMode: z9.literal("assistant_prose"),
667
+ applyGuidance: z9.string()
668
+ }).strict(),
669
+ assistantGuidance: z9.string()
670
+ }).strict();
671
+ exports.CALENDAR_SUGGEST_PUBLISH_TIMES_CONTRACT = defineToolContract({
672
+ canonicalName: exports.TOOL_OPERATION_IDS.calendarSuggestPublishTimes,
673
+ wireNames: exports.TOOL_WIRE_NAMES.calendarSuggestPublishTimes,
674
+ description: "Suggest read-only candidate publish times from the current workspace calendar for a date range. It does not schedule, reschedule, publish, edit, or delete content.",
675
+ inputSchema: exports.calendarSuggestPublishTimesInputSchema,
676
+ outputSchema: exports.calendarSuggestPublishTimesOutputSchema,
677
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.workspaceRead],
678
+ confirmation: { required: false },
679
+ idempotency: { required: false },
680
+ surfaces: {
681
+ agent: {
682
+ name: exports.TOOL_WIRE_NAMES.calendarSuggestPublishTimes.agent,
683
+ description: "Suggest good candidate publish times in a date range from the current workspace calendar. Read-only: it returns candidate times with reasons and does not schedule, reschedule, publish, edit, or delete anything. Use it when the user asks for a good, open, light, or recommended time to post. Pass startDate and endDate as timezone-qualified ISO 8601 timestamps using the workspace timezone offset (for example 2026-07-13T00:00:00+10:00), covering the full local days to consider. To apply a chosen candidate to the open composer, call composer.patch_schedule with that scheduledAt.",
684
+ access: "read",
685
+ gated: false,
686
+ safeInputSummary: (input) => `range=${input.startDate}..${input.endDate} step=${input.candidateStepMinutes} gap=${input.minGapMinutes} limit=${input.limit}`
687
+ }
688
+ }
689
+ });
690
+ exports.mediaSearchInputSchema = z9.object({
691
+ query: z9.string().trim().min(1).max(120).optional(),
692
+ type: z9.enum(["image", "video", "gif"]).optional(),
693
+ limit: z9.number().int().min(1).max(20).default(8)
694
+ }).strict();
695
+ exports.mediaSearchOutputSchema = z9.object({
696
+ ok: z9.literal(true),
697
+ renderHint: z9.literal("media_refs"),
698
+ items: z9.array(boundedStringRecordSchema),
699
+ validatedChannels: z9.array(z9.string()).optional()
700
+ }).strict();
701
+ exports.MEDIA_SEARCH_CONTRACT = defineToolContract({
702
+ canonicalName: exports.TOOL_OPERATION_IDS.mediaSearch,
703
+ wireNames: exports.TOOL_WIRE_NAMES.mediaSearch,
704
+ description: "Search active media library metadata in the current workspace and return selectable media refs.",
705
+ inputSchema: exports.mediaSearchInputSchema,
706
+ outputSchema: exports.mediaSearchOutputSchema,
707
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.mediaRead],
708
+ confirmation: { required: false },
709
+ idempotency: { required: false },
710
+ surfaces: {
711
+ agent: {
712
+ name: exports.TOOL_WIRE_NAMES.mediaSearch.agent,
713
+ description: "Search active media library metadata in the current workspace and return selectable media refs. When a composer draft is open, results are ordered channel-valid first and each item may carry channelValid and channelWarnings for the draft's selected channels; prefer channel-valid assets and surface warnings before publish.",
714
+ access: "read",
715
+ gated: false,
716
+ safeInputSummary: (input) => `query=${input.query ?? "none"} type=${input.type ?? "any"} limit=${input.limit}`
717
+ }
718
+ }
719
+ });
720
+ exports.composerPatchCaptionInputSchema = z9.object({
721
+ caption: z9.string().trim().min(1).max(2200),
722
+ platform: z9.string().trim().min(1).max(40).optional(),
723
+ field: z9.enum(["caption", "firstComment"]).default("caption")
724
+ }).strict();
725
+ exports.composerPatchScheduleInputSchema = z9.object({
726
+ scheduledAt: z9.string().datetime({ offset: true }).nullable().optional(),
727
+ timezone: z9.string().trim().min(1).max(100).optional()
728
+ }).strict().refine((input) => input.scheduledAt !== void 0 || input.timezone !== void 0, {
729
+ message: "Provide at least one schedule field."
730
+ });
731
+ exports.composerPatchTaxonomyInputSchema = z9.object({
732
+ labelIds: z9.array(z9.string().uuid()).max(30).optional(),
733
+ pillarIds: z9.array(z9.string().uuid()).max(30).optional(),
734
+ formatIds: z9.array(z9.string().uuid()).max(10).optional(),
735
+ hashtags: z9.array(z9.string().trim().min(1).max(80)).max(30).optional()
736
+ }).strict().refine((input) => Boolean(input.labelIds?.length || input.pillarIds?.length || input.formatIds?.length || input.hashtags?.length), {
737
+ message: "Provide at least one taxonomy field."
738
+ });
739
+ var composerPatchMediaMaxItems = 10;
740
+ var composerPatchMediaItemSchema = z9.object({
741
+ mediaId: z9.string().uuid(),
742
+ order: z9.number().int().min(0).optional(),
743
+ crops: z9.record(z9.string(), z9.unknown()).optional(),
744
+ userTags: z9.array(z9.unknown()).optional(),
745
+ productTags: z9.array(z9.unknown()).optional(),
746
+ cover: z9.record(z9.string(), z9.unknown()).nullable().optional()
747
+ }).strict();
748
+ exports.composerPatchMediaInputSchema = z9.object({
749
+ contentMedia: z9.array(composerPatchMediaItemSchema).max(composerPatchMediaMaxItems)
750
+ }).strict().superRefine((input, ctx) => {
751
+ const seenMediaIds = /* @__PURE__ */ new Set();
752
+ const seenOrders = /* @__PURE__ */ new Set();
753
+ input.contentMedia.forEach((item, index) => {
754
+ if (seenMediaIds.has(item.mediaId)) {
755
+ ctx.addIssue({
756
+ code: "custom",
757
+ path: ["contentMedia", index, "mediaId"],
758
+ message: `Duplicate contentMedia mediaId: ${item.mediaId}.`
759
+ });
760
+ }
761
+ seenMediaIds.add(item.mediaId);
762
+ if (item.order === void 0)
763
+ return;
764
+ if (seenOrders.has(item.order)) {
765
+ ctx.addIssue({
766
+ code: "custom",
767
+ path: ["contentMedia", index, "order"],
768
+ message: `Duplicate contentMedia order: ${item.order}.`
769
+ });
770
+ }
771
+ seenOrders.add(item.order);
772
+ });
773
+ });
774
+ exports.composerPatchCaptionArtifactMetadataSchema = z9.object({
775
+ targetDraftId: z9.string(),
776
+ operation: z9.literal("caption.patch"),
777
+ field: z9.enum(["caption", "firstComment"]),
778
+ platform: z9.string().optional(),
779
+ afterPreview: z9.string(),
780
+ afterLength: z9.number().int().nonnegative(),
781
+ beforePreview: z9.string().nullable(),
782
+ beforeLength: z9.number().int().nonnegative().nullable()
783
+ }).strict();
784
+ exports.composerPatchScheduleArtifactMetadataSchema = z9.object({
785
+ targetDraftId: z9.string(),
786
+ operation: z9.literal("schedule.patch"),
787
+ scheduledAt: z9.string().nullable().optional(),
788
+ timezone: z9.string().optional()
789
+ }).strict();
790
+ var composerPatchTaxonomyChangedFieldSchema = z9.enum(["labels", "pillars", "formats", "hashtags"]);
791
+ exports.composerPatchTaxonomyArtifactMetadataSchema = z9.object({
792
+ targetDraftId: z9.string(),
793
+ operation: z9.literal("taxonomy.patch"),
794
+ changedFields: z9.array(composerPatchTaxonomyChangedFieldSchema),
795
+ labelsBefore: z9.number().int().nonnegative().nullable().optional(),
796
+ labelsAfter: z9.number().int().nonnegative().optional(),
797
+ pillarsBefore: z9.number().int().nonnegative().nullable().optional(),
798
+ pillarsAfter: z9.number().int().nonnegative().optional(),
799
+ formatsBefore: z9.number().int().nonnegative().nullable().optional(),
800
+ formatsAfter: z9.number().int().nonnegative().optional(),
801
+ hashtags: z9.array(z9.string()).optional()
802
+ }).strict();
803
+ exports.composerPatchMediaArtifactMetadataSchema = z9.object({
804
+ targetDraftId: z9.string(),
805
+ operation: z9.literal("media.patch"),
806
+ beforeCount: z9.number().int().nonnegative().nullable(),
807
+ afterCount: z9.number().int().nonnegative(),
808
+ addedMediaIds: z9.array(z9.string()).max(composerPatchMediaMaxItems),
809
+ removedMediaIds: z9.array(z9.string()).max(composerPatchMediaMaxItems)
810
+ }).strict();
811
+ exports.composerPatchArtifactMetadataSchema = z9.discriminatedUnion("operation", [
812
+ exports.composerPatchCaptionArtifactMetadataSchema,
813
+ exports.composerPatchScheduleArtifactMetadataSchema,
814
+ exports.composerPatchTaxonomyArtifactMetadataSchema,
815
+ exports.composerPatchMediaArtifactMetadataSchema
816
+ ]);
817
+ exports.composerPatchOutputSchema = z9.object({
818
+ ok: z9.boolean(),
819
+ renderHint: z9.literal("composer_patch"),
820
+ patch: z9.object({
821
+ patchId: z9.string(),
822
+ targetDraftId: z9.string(),
823
+ expectedRevision: z9.string(),
824
+ operation: z9.string(),
825
+ payload: z9.record(z9.string(), z9.unknown()),
826
+ createdAt: z9.string()
827
+ }).strict()
828
+ }).strict();
829
+ exports.COMPOSER_PATCH_CAPTION_CONTRACT = defineToolContract({
830
+ canonicalName: exports.TOOL_OPERATION_IDS.composerPatchCaption,
831
+ wireNames: exports.TOOL_WIRE_NAMES.composerPatchCaption,
832
+ description: "Create a browser-owned composer patch that replaces a caption or first comment.",
833
+ inputSchema: exports.composerPatchCaptionInputSchema,
834
+ outputSchema: exports.composerPatchOutputSchema,
835
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.contentDraftUpdate],
836
+ confirmation: { required: false },
837
+ idempotency: { required: true },
838
+ surfaces: {
839
+ agent: {
840
+ name: exports.TOOL_WIRE_NAMES.composerPatchCaption.agent,
841
+ description: "Create a browser-owned composer patch that replaces a caption or first comment.",
842
+ access: "write",
843
+ gated: false,
844
+ safeInputSummary: (input) => `targetDraftId=current field=${input.field ?? "caption"} captionLength=${input.caption.length}`
845
+ }
846
+ }
847
+ });
848
+ exports.COMPOSER_PATCH_SCHEDULE_CONTRACT = defineToolContract({
849
+ canonicalName: exports.TOOL_OPERATION_IDS.composerPatchSchedule,
850
+ wireNames: exports.TOOL_WIRE_NAMES.composerPatchSchedule,
851
+ description: "Create a browser-owned composer patch for schedule fields.",
852
+ inputSchema: exports.composerPatchScheduleInputSchema,
853
+ outputSchema: exports.composerPatchOutputSchema,
854
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.contentDraftUpdate],
855
+ confirmation: { required: false },
856
+ idempotency: { required: true },
857
+ surfaces: {
858
+ agent: {
859
+ name: exports.TOOL_WIRE_NAMES.composerPatchSchedule.agent,
860
+ description: "Create a browser-owned composer patch for schedule fields.",
861
+ access: "write",
862
+ gated: false,
863
+ safeInputSummary: (input) => `targetDraftId=current scheduledAt=${input.scheduledAt ?? "unchanged"} timezone=${input.timezone ?? "unchanged"}`
864
+ }
865
+ }
866
+ });
867
+ exports.COMPOSER_PATCH_TAXONOMY_CONTRACT = defineToolContract({
868
+ canonicalName: exports.TOOL_OPERATION_IDS.composerPatchTaxonomy,
869
+ wireNames: exports.TOOL_WIRE_NAMES.composerPatchTaxonomy,
870
+ description: "Create a browser-owned composer patch for labels, pillars, formats, or hashtags.",
871
+ inputSchema: exports.composerPatchTaxonomyInputSchema,
872
+ outputSchema: exports.composerPatchOutputSchema,
873
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.contentDraftUpdate],
874
+ confirmation: { required: false },
875
+ idempotency: { required: true },
876
+ surfaces: {
877
+ agent: {
878
+ name: exports.TOOL_WIRE_NAMES.composerPatchTaxonomy.agent,
879
+ description: "Create a browser-owned composer patch for labels, pillars, formats, or hashtags.",
880
+ access: "write",
881
+ gated: false,
882
+ safeInputSummary: (input) => [
883
+ "targetDraftId=current",
884
+ `labels=${input.labelIds?.length ?? 0}`,
885
+ `pillars=${input.pillarIds?.length ?? 0}`,
886
+ `formats=${input.formatIds?.length ?? 0}`,
887
+ `hashtags=${input.hashtags?.length ?? 0}`
888
+ ].join(" ")
889
+ }
890
+ }
891
+ });
892
+ exports.COMPOSER_PATCH_MEDIA_CONTRACT = defineToolContract({
893
+ canonicalName: exports.TOOL_OPERATION_IDS.composerPatchMedia,
894
+ wireNames: exports.TOOL_WIRE_NAMES.composerPatchMedia,
895
+ description: "Create a browser-owned composer patch that replaces the open draft's media list.",
896
+ inputSchema: exports.composerPatchMediaInputSchema,
897
+ outputSchema: exports.composerPatchOutputSchema,
898
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.contentDraftUpdate],
899
+ confirmation: { required: false },
900
+ idempotency: { required: true },
901
+ surfaces: {
902
+ agent: {
903
+ name: exports.TOOL_WIRE_NAMES.composerPatchMedia.agent,
904
+ description: "Create a browser-owned composer patch that replaces the open draft's media list.",
905
+ access: "write",
906
+ gated: false,
907
+ safeInputSummary: (input) => `targetDraftId=current media=${input.contentMedia.length}`
908
+ }
909
+ }
910
+ });
911
+ var publicContentStatuses = ["draft", "scheduled", "sent", "failed"];
912
+ var contentWorkflowStatuses = ["drafting", "review", "approved", "scheduled", "published"];
913
+ var publicContentSortFields = ["createdAt", "updatedAt", "scheduledAt", "priority"];
914
+ var publicContentSortDirections = ["asc", "desc"];
915
+ var reviewLifecyclePhases = ["none", "internal", "client"];
916
+ var reviewLifecycleStates = [
917
+ "none",
918
+ "internal_review_pending",
919
+ "internal_review_approved",
920
+ "internal_review_outdated",
921
+ "internal_changes_requested",
922
+ "internal_review_withdrawn",
923
+ "waiting_internal_before_client",
924
+ "ready_to_send_to_client",
925
+ "client_review_active",
926
+ "client_review_outdated",
927
+ "client_changes_requested",
928
+ "client_review_approved",
929
+ "client_review_admin_overridden",
930
+ "client_review_cancelled",
931
+ "client_review_expired"
932
+ ];
933
+ var reviewLifecycleActors = ["none", "agency", "author", "approver", "client", "system"];
934
+ var reviewLifecycleNextActions = [
935
+ "none",
936
+ "request_internal_approval",
937
+ "complete_internal_review",
938
+ "address_internal_changes",
939
+ "send_to_client",
940
+ "notify_client",
941
+ "wait_for_client",
942
+ "address_client_changes",
943
+ "refresh_client_share",
944
+ "schedule",
945
+ "publish",
946
+ "set_intended_publish_time"
947
+ ];
948
+ var reviewLifecycleBlockerCodes = [
949
+ "missing_schedule",
950
+ "schedule_expired",
951
+ "internal_approval_pending",
952
+ "internal_changes_requested",
953
+ "client_review_not_sent",
954
+ "client_review_pending",
955
+ "client_review_outdated",
956
+ "client_changes_requested",
957
+ "client_review_cancelled",
958
+ "client_review_expired",
959
+ "missing_review_snapshot",
960
+ "review_snapshot_hash_mismatch"
961
+ ];
962
+ exports.contentListMcpInputSchema = z9.object({
963
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
964
+ status: z9.enum(publicContentStatuses).optional().describe("Optional content status filter."),
965
+ workflowStatus: z9.enum(contentWorkflowStatuses).optional().describe("Optional workflow status filter."),
966
+ workflowStatuses: z9.array(z9.enum(contentWorkflowStatuses)).optional().describe("Optional workflow status filters. Takes precedence over workflowStatus."),
967
+ includeReviewLifecycle: z9.boolean().optional().describe("Include reviewLifecycle on items without changing the default public status filter."),
968
+ reviewLifecyclePhase: z9.enum(reviewLifecyclePhases).optional().describe("Filter by reviewLifecycle.phase. Also opts into review-held content."),
969
+ reviewLifecycleState: z9.enum(reviewLifecycleStates).optional().describe("Filter by reviewLifecycle.state. Also opts into review-held content."),
970
+ reviewLifecycleActor: z9.enum(reviewLifecycleActors).optional().describe("Filter by reviewLifecycle.actor. Also opts into review-held content."),
971
+ reviewLifecycleNextAction: z9.enum(reviewLifecycleNextActions).optional().describe("Filter by reviewLifecycle.nextAction. Also opts into review-held content."),
972
+ reviewLifecycleBlocksPublishing: z9.boolean().optional().describe("Filter by whether reviewLifecycle currently blocks scheduling or publishing."),
973
+ reviewLifecycleBlocker: z9.enum(reviewLifecycleBlockerCodes).optional().describe("Filter by a reviewLifecycle blocker code. Also opts into review-held content."),
974
+ reviewLifecycleBatchId: z9.string().uuid().optional().describe("Filter by reviewLifecycle.clientReview.batchId. Also opts into review-held content."),
975
+ reviewLifecycleItemId: z9.string().uuid().optional().describe("Filter by reviewLifecycle.clientReview.itemId. Also opts into review-held content."),
976
+ integrationId: z9.string().uuid().optional().describe("Optional integration ID filter."),
977
+ sortBy: z9.enum(publicContentSortFields).optional().describe("Optional sort field."),
978
+ sortDirection: z9.enum(publicContentSortDirections).optional().describe("Optional sort direction."),
979
+ limit: z9.number().int().min(1).max(100).optional().describe("Page size, default 20, maximum 100."),
980
+ offset: z9.number().int().min(0).optional().describe("Offset for pagination, default 0.")
981
+ }).strict();
982
+ exports.contentListInputSchema = z9.object({
983
+ status: z9.enum(publicContentStatuses).optional().describe("Optional content status filter."),
984
+ workflowStatus: z9.enum(contentWorkflowStatuses).optional().describe("Optional workflow status filter."),
985
+ workflowStatuses: z9.array(z9.enum(contentWorkflowStatuses)).optional().describe("Optional workflow status filters. Takes precedence over workflowStatus."),
986
+ includeReviewLifecycle: z9.boolean().optional().describe("Include reviewLifecycle on items without changing the default public status filter."),
987
+ reviewLifecyclePhase: z9.enum(reviewLifecyclePhases).optional().describe("Filter by reviewLifecycle.phase. Also opts into review-held content."),
988
+ reviewLifecycleState: z9.enum(reviewLifecycleStates).optional().describe("Filter by reviewLifecycle.state. Also opts into review-held content."),
989
+ reviewLifecycleActor: z9.enum(reviewLifecycleActors).optional().describe("Filter by reviewLifecycle.actor. Also opts into review-held content."),
990
+ reviewLifecycleNextAction: z9.enum(reviewLifecycleNextActions).optional().describe("Filter by reviewLifecycle.nextAction. Also opts into review-held content."),
991
+ reviewLifecycleBlocksPublishing: z9.boolean().optional().describe("Filter by whether reviewLifecycle currently blocks scheduling or publishing."),
992
+ reviewLifecycleBlocker: z9.enum(reviewLifecycleBlockerCodes).optional().describe("Filter by a reviewLifecycle blocker code. Also opts into review-held content."),
993
+ reviewLifecycleBatchId: z9.string().uuid().optional().describe("Filter by reviewLifecycle.clientReview.batchId. Also opts into review-held content."),
994
+ reviewLifecycleItemId: z9.string().uuid().optional().describe("Filter by reviewLifecycle.clientReview.itemId. Also opts into review-held content."),
995
+ integrationId: z9.string().uuid().optional().describe("Optional integration ID filter."),
996
+ sortBy: z9.enum(publicContentSortFields).optional().describe("Optional sort field."),
997
+ sortDirection: z9.enum(publicContentSortDirections).optional().describe("Optional sort direction."),
998
+ limit: z9.number().int().min(1).max(100).optional().describe("Page size, default 20, maximum 100."),
999
+ offset: z9.number().int().min(0).optional().describe("Offset for pagination, default 0.")
1000
+ }).strict();
1001
+ exports.contentListAgentInputSchema = exports.contentListInputSchema.omit({ limit: true }).extend({
1002
+ limit: z9.number().int().min(1).max(20).default(10).describe("Page size, default 10, maximum 20. List items carry full captions, so keep this small.")
1003
+ }).strict();
1004
+ exports.contentGetCountsInputSchema = z9.object({
1005
+ includePendingApproval: z9.boolean().optional().describe("Include pending approval count. Requires Standard or Premium plan.")
1006
+ }).strict();
1007
+ exports.contentGetInputSchema = z9.object({
1008
+ contentId: z9.string().uuid().describe("Content ID to retrieve.")
1009
+ }).strict();
1010
+ exports.contentGetMcpInputSchema = z9.object({
1011
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
1012
+ contentId: z9.string().uuid().describe("Content ID to retrieve.")
1013
+ }).strict();
1014
+ exports.contentGetCountsMcpInputSchema = z9.object({
1015
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
1016
+ includePendingApproval: z9.boolean().optional().describe("Include pending approval count. Requires Standard or Premium plan.")
1017
+ }).strict();
1018
+ var contentSelectionToolsets = ["content_selection", "content_read_only", "content_workflow", "content_workflow_all"];
1019
+ exports.CONTENT_LIST_CONTRACT = {
1020
+ canonicalName: exports.TOOL_OPERATION_IDS.contentList,
1021
+ wireNames: exports.TOOL_WIRE_NAMES.contentList,
1022
+ description: "List Maeve content for a workspace using public API filters and sanitized output. Defaults intentionally exclude review-held pending_approval content; explicit reviewLifecycle filters opt into review-held content and include reviewLifecycle on items.",
1023
+ inputSchema: exports.contentListInputSchema,
1024
+ wireInputSchemas: {
1025
+ agent: exports.contentListAgentInputSchema,
1026
+ mcp: exports.contentListMcpInputSchema
1027
+ },
1028
+ outputSchema: mcpStructuredContentOutputSchema,
1029
+ // workspace.read is granted to every workspace role; the agent runner denies an
1030
+ // empty capability list outright (capabilities.some on [] is false), so reads
1031
+ // promoted to the agent surface must carry at least one capability.
1032
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.workspaceRead],
1033
+ confirmation: { required: false },
1034
+ idempotency: { required: false },
1035
+ surfaces: {
1036
+ agent: {
1037
+ name: exports.TOOL_WIRE_NAMES.contentList.agent,
1038
+ description: "List saved content in the current workspace with status, workflow, review-lifecycle, integration, and sort filters. Items include full captions, so keep limit small and page with offset. Prefer content.find_recent for a quick recency scan. Read-only.",
1039
+ access: "read",
1040
+ gated: false,
1041
+ safeInputSummary: (input) => `status=${input.status ?? "any"} limit=${input.limit ?? 10} offset=${input.offset ?? 0}`
1042
+ },
1043
+ mcp: {
1044
+ name: exports.TOOL_WIRE_NAMES.contentList.mcp,
1045
+ title: "List Content",
1046
+ description: "List Maeve content for a workspace using public API filters and sanitized output. Defaults intentionally exclude review-held pending_approval content; explicit reviewLifecycle filters opt into review-held content and include reviewLifecycle on items.",
1047
+ scope: "mcp:read",
1048
+ toolsets: contentSelectionToolsets,
1049
+ annotations: mcpReadAnnotations
1050
+ }
1051
+ }
1052
+ };
1053
+ exports.CONTENT_GET_CONTRACT = {
1054
+ canonicalName: exports.TOOL_OPERATION_IDS.contentGet,
1055
+ wireNames: exports.TOOL_WIRE_NAMES.contentGet,
1056
+ description: "Get one Maeve content item with public API detail fields, sanitized media, and sanitized platform settings. When reviewLifecycle is present, use its state, blockers, and nextAction instead of content.status alone for review workflow decisions.",
1057
+ inputSchema: exports.contentGetInputSchema,
1058
+ wireInputSchemas: {
1059
+ mcp: exports.contentGetMcpInputSchema
1060
+ },
1061
+ outputSchema: mcpStructuredContentOutputSchema,
1062
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.workspaceRead],
1063
+ confirmation: { required: false },
1064
+ idempotency: { required: false },
1065
+ surfaces: {
1066
+ agent: {
1067
+ name: exports.TOOL_WIRE_NAMES.contentGet.agent,
1068
+ description: "Read one saved content item in the current workspace, including sanitized media, captions, workflow metadata, and platform settings.",
1069
+ access: "read",
1070
+ gated: false,
1071
+ safeInputSummary: (input) => `contentId=${input.contentId}`
1072
+ },
1073
+ mcp: {
1074
+ name: exports.TOOL_WIRE_NAMES.contentGet.mcp,
1075
+ title: "Get Content",
1076
+ description: "Get one Maeve content item with public API detail fields, sanitized media, and sanitized platform settings. When reviewLifecycle is present, use its state, blockers, and nextAction instead of content.status alone for review workflow decisions.",
1077
+ scope: "mcp:read",
1078
+ toolsets: contentSelectionToolsets,
1079
+ annotations: mcpReadAnnotations
1080
+ }
1081
+ }
1082
+ };
1083
+ exports.CONTENT_GET_COUNTS_CONTRACT = {
1084
+ canonicalName: exports.TOOL_OPERATION_IDS.contentGetCounts,
1085
+ wireNames: exports.TOOL_WIRE_NAMES.contentGetCounts,
1086
+ description: "Get safe content workflow counts for an Maeve workspace, including failed content and premium-plan pending approvals.",
1087
+ inputSchema: exports.contentGetCountsInputSchema,
1088
+ wireInputSchemas: {
1089
+ mcp: exports.contentGetCountsMcpInputSchema
1090
+ },
1091
+ outputSchema: mcpStructuredContentOutputSchema,
1092
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.workspaceRead],
1093
+ confirmation: { required: false },
1094
+ idempotency: { required: false },
1095
+ surfaces: {
1096
+ agent: {
1097
+ name: exports.TOOL_WIRE_NAMES.contentGetCounts.agent,
1098
+ description: "Read safe content workflow counts for the current workspace: failed content, plus pending approvals when includePendingApproval is true. Cheap way to check whether anything needs attention before listing. Read-only.",
1099
+ access: "read",
1100
+ gated: false,
1101
+ safeInputSummary: (input) => `includePendingApproval=${input.includePendingApproval ?? false}`
1102
+ },
1103
+ mcp: {
1104
+ name: exports.TOOL_WIRE_NAMES.contentGetCounts.mcp,
1105
+ title: "Get Content Counts",
1106
+ description: "Get safe content workflow counts for an Maeve workspace, including failed content and premium-plan pending approvals.",
1107
+ scope: "mcp:read",
1108
+ toolsets: contentSelectionToolsets,
1109
+ annotations: mcpReadAnnotations
1110
+ }
1111
+ }
1112
+ };
1113
+ var contentTaxonomyContextToolsets = [
1114
+ "content_taxonomy_context",
1115
+ "content_read_only",
1116
+ "content_workflow",
1117
+ "content_workflow_all"
1118
+ ];
1119
+ var contentIntegrationContextToolsets = [
1120
+ "content_integration_context",
1121
+ "content_read_only",
1122
+ "content_workflow",
1123
+ "content_workflow_all",
1124
+ "analytics_context",
1125
+ "analytics_read_only"
1126
+ ];
1127
+ var integrationInspectionToolsets = [
1128
+ "content_integration_context",
1129
+ "content_read_only",
1130
+ "content_workflow",
1131
+ "content_workflow_all"
1132
+ ];
1133
+ exports.integrationsListInputSchema = z9.object({}).strict();
1134
+ exports.integrationsListMcpInputSchema = z9.object({
1135
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID.")
1136
+ }).strict();
1137
+ exports.INTEGRATION_OPTION_KEYS = [
1138
+ "pinterest-boards",
1139
+ "tiktok-creator-info",
1140
+ "locations",
1141
+ "instagram-catalogs",
1142
+ "instagram-products",
1143
+ "youtube-video-categories"
1144
+ ];
1145
+ exports.integrationsGetCapabilitiesInputSchema = z9.object({
1146
+ integrationId: z9.string().uuid().describe("Integration ID to inspect. Use integrations.list to resolve account names to IDs.")
1147
+ }).strict();
1148
+ exports.integrationsGetCapabilitiesMcpInputSchema = z9.object({
1149
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
1150
+ integrationId: z9.string().uuid().describe("Maeve integration ID.")
1151
+ }).strict();
1152
+ var integrationOptionRequestShape = {
1153
+ regionCode: z9.string().max(2).optional().describe("Optional ISO country code, for example US."),
1154
+ query: z9.string().max(255).optional().describe("Search text for locations or products."),
1155
+ catalogId: z9.string().max(255).optional().describe("Instagram catalog ID for product search.")
1156
+ };
1157
+ exports.integrationsGetOptionsInputSchema = z9.object({
1158
+ integrationId: z9.string().uuid().describe("Integration ID to inspect. Use integrations.list to resolve account names to IDs."),
1159
+ optionKey: z9.enum(exports.INTEGRATION_OPTION_KEYS).describe("Option key listed by the integration capabilities options list."),
1160
+ input: z9.object(integrationOptionRequestShape).strict().optional().describe("Option-specific input.")
1161
+ }).strict();
1162
+ exports.integrationsGetOptionsMcpInputSchema = z9.object({
1163
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
1164
+ integrationId: z9.string().uuid().describe("Maeve integration ID."),
1165
+ optionKey: z9.enum(exports.INTEGRATION_OPTION_KEYS).describe("Option key returned by capabilities."),
1166
+ input: z9.object(integrationOptionRequestShape).optional().describe("Option-specific input.")
1167
+ }).strict();
1168
+ var listTaxonomyInputShape = {
1169
+ labelSearch: z9.string().max(200).optional().describe("Optional label name search."),
1170
+ includeArchived: z9.boolean().optional().describe("Include archived content pillars and formats. Labels remain active/unmerged by default.")
1171
+ };
1172
+ exports.taxonomyListInputSchema = z9.object(listTaxonomyInputShape).strict();
1173
+ exports.taxonomyListMcpInputSchema = z9.object({
1174
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
1175
+ ...listTaxonomyInputShape
1176
+ }).strict();
1177
+ var listCampaignsInputShape = {
1178
+ search: z9.string().max(200).optional().describe("Optional campaign name search."),
1179
+ includeArchived: z9.boolean().optional().describe("Include archived campaigns."),
1180
+ includePhases: z9.boolean().optional().describe("Include nested campaign phases.")
1181
+ };
1182
+ exports.campaignsListInputSchema = z9.object(listCampaignsInputShape).strict();
1183
+ exports.campaignsListMcpInputSchema = z9.object({
1184
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
1185
+ ...listCampaignsInputShape
1186
+ }).strict();
1187
+ exports.hashtagGroupsListInputSchema = z9.object({}).strict();
1188
+ exports.hashtagGroupsListMcpInputSchema = z9.object({
1189
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID.")
1190
+ }).strict();
1191
+ var integrationListItemOutputSchema = z9.object({
1192
+ id: z9.string(),
1193
+ platform: z9.string(),
1194
+ username: z9.string().nullable(),
1195
+ name: z9.string().nullable(),
1196
+ displayName: z9.string().nullable(),
1197
+ status: z9.enum(["connected", "requires_reauth", "disabled", "auth_incomplete"])
1198
+ }).strict();
1199
+ exports.integrationsListOutputSchema = z9.object({
1200
+ integrations: z9.array(integrationListItemOutputSchema)
1201
+ }).strict();
1202
+ var taxonomyLabelOutputSchema = z9.object({
1203
+ id: z9.string(),
1204
+ name: z9.string(),
1205
+ color: z9.string().nullable(),
1206
+ groupId: z9.string().nullable(),
1207
+ archivedAt: z9.string().nullable(),
1208
+ mergedIntoLabelId: z9.string().nullable(),
1209
+ mergedAt: z9.string().nullable(),
1210
+ createdAt: z9.string(),
1211
+ updatedAt: z9.string()
1212
+ }).strict();
1213
+ var taxonomyPillarOutputSchema = z9.object({
1214
+ id: z9.string(),
1215
+ name: z9.string(),
1216
+ color: z9.string().nullable(),
1217
+ description: z9.string().nullable(),
1218
+ createdAt: z9.string(),
1219
+ updatedAt: z9.string(),
1220
+ sortOrder: z9.number(),
1221
+ archivedAt: z9.string().nullable()
1222
+ }).strict();
1223
+ var taxonomyFormatOutputSchema = z9.object({
1224
+ id: z9.string(),
1225
+ name: z9.string(),
1226
+ color: z9.string().nullable(),
1227
+ description: z9.string().nullable(),
1228
+ isSeeded: z9.boolean(),
1229
+ createdAt: z9.string(),
1230
+ updatedAt: z9.string(),
1231
+ sortOrder: z9.number(),
1232
+ archivedAt: z9.string().nullable()
1233
+ }).strict();
1234
+ exports.taxonomyListOutputSchema = z9.object({
1235
+ labels: z9.array(taxonomyLabelOutputSchema),
1236
+ pillars: z9.array(taxonomyPillarOutputSchema),
1237
+ formats: z9.array(taxonomyFormatOutputSchema)
1238
+ }).strict();
1239
+ var campaignPhaseOutputSchema = z9.object({
1240
+ id: z9.string(),
1241
+ workspaceId: z9.string(),
1242
+ campaignId: z9.string(),
1243
+ name: z9.string(),
1244
+ color: z9.string().nullable(),
1245
+ startDate: z9.string().nullable(),
1246
+ endDate: z9.string().nullable(),
1247
+ sortOrder: z9.number(),
1248
+ createdAt: z9.string(),
1249
+ updatedAt: z9.string()
1250
+ }).strict();
1251
+ var campaignOutputSchema = z9.object({
1252
+ id: z9.string(),
1253
+ workspaceId: z9.string(),
1254
+ name: z9.string(),
1255
+ color: z9.string().nullable(),
1256
+ goal: z9.string().nullable(),
1257
+ description: z9.string().nullable(),
1258
+ startDate: z9.string(),
1259
+ endDate: z9.string(),
1260
+ status: z9.enum(["upcoming", "live", "ended"]),
1261
+ targetPlatforms: z9.array(z9.string()),
1262
+ estimatedBudget: z9.string().nullable(),
1263
+ actualBudget: z9.string().nullable(),
1264
+ budgetCurrency: z9.string().nullable(),
1265
+ archivedAt: z9.string().nullable(),
1266
+ createdByUserId: z9.string().nullable(),
1267
+ updatedByUserId: z9.string().nullable(),
1268
+ createdAt: z9.string(),
1269
+ updatedAt: z9.string(),
1270
+ phases: z9.array(campaignPhaseOutputSchema).optional()
1271
+ }).strict();
1272
+ exports.campaignsListOutputSchema = z9.object({
1273
+ campaigns: z9.array(campaignOutputSchema)
1274
+ }).strict();
1275
+ var hashtagGroupOutputSchema = z9.object({
1276
+ id: z9.string(),
1277
+ name: z9.string(),
1278
+ content: z9.string(),
1279
+ createdAt: z9.string(),
1280
+ updatedAt: z9.string()
1281
+ }).strict();
1282
+ exports.hashtagGroupsListOutputSchema = z9.object({
1283
+ hashtagGroups: z9.array(hashtagGroupOutputSchema)
1284
+ }).strict();
1285
+ exports.INTEGRATIONS_LIST_CONTRACT = {
1286
+ canonicalName: exports.TOOL_OPERATION_IDS.integrationsList,
1287
+ wireNames: exports.TOOL_WIRE_NAMES.integrationsList,
1288
+ description: "List social integrations for an Maeve workspace. Returns only safe public metadata and connection status.",
1289
+ inputSchema: exports.integrationsListInputSchema,
1290
+ wireInputSchemas: {
1291
+ mcp: exports.integrationsListMcpInputSchema
1292
+ },
1293
+ outputSchema: exports.integrationsListOutputSchema,
1294
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.workspaceRead],
1295
+ confirmation: { required: false },
1296
+ idempotency: { required: false },
1297
+ surfaces: {
1298
+ agent: {
1299
+ name: exports.TOOL_WIRE_NAMES.integrationsList.agent,
1300
+ description: "List the connected social integrations in the current workspace with safe public metadata and connection status. Use it to resolve account names to integration IDs.",
1301
+ access: "read",
1302
+ gated: false,
1303
+ safeInputSummary: () => "current workspace integrations"
1304
+ },
1305
+ mcp: {
1306
+ name: exports.TOOL_WIRE_NAMES.integrationsList.mcp,
1307
+ title: "List Integrations",
1308
+ description: "List social integrations for an Maeve workspace. Returns only safe public metadata and connection status.",
1309
+ scope: "mcp:read",
1310
+ toolsets: contentIntegrationContextToolsets,
1311
+ annotations: mcpReadAnnotations
1312
+ }
1313
+ }
1314
+ };
1315
+ exports.INTEGRATIONS_GET_CAPABILITIES_CONTRACT = {
1316
+ canonicalName: exports.TOOL_OPERATION_IDS.integrationsGetCapabilities,
1317
+ wireNames: exports.TOOL_WIRE_NAMES.integrationsGetCapabilities,
1318
+ description: "Get safe publishing capabilities for one workspace integration. Does not expose tokens, stored settings, scopes, or raw provider payloads.",
1319
+ inputSchema: exports.integrationsGetCapabilitiesInputSchema,
1320
+ wireInputSchemas: {
1321
+ mcp: exports.integrationsGetCapabilitiesMcpInputSchema
1322
+ },
1323
+ outputSchema: mcpStructuredContentOutputSchema,
1324
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.integrationsRead],
1325
+ confirmation: { required: false },
1326
+ idempotency: { required: false },
1327
+ surfaces: {
1328
+ agent: {
1329
+ name: exports.TOOL_WIRE_NAMES.integrationsGetCapabilities.agent,
1330
+ description: "Read what one connected channel supports before drafting or scheduling for it: post types, media types and limits, thread support, required fields, platform rules, provider settings fields, and the dynamic option keys available through integrations.get_options. Read-only.",
1331
+ access: "read",
1332
+ gated: false,
1333
+ safeInputSummary: (input) => `integrationId=${input.integrationId}`
1334
+ },
1335
+ mcp: {
1336
+ name: exports.TOOL_WIRE_NAMES.integrationsGetCapabilities.mcp,
1337
+ title: "Get Integration Capabilities",
1338
+ description: "Get safe publishing capabilities for one workspace integration. Does not expose tokens, stored settings, scopes, or raw provider payloads.",
1339
+ scope: "mcp:read",
1340
+ toolsets: integrationInspectionToolsets,
1341
+ annotations: mcpReadAnnotations
1342
+ }
1343
+ }
1344
+ };
1345
+ exports.INTEGRATIONS_GET_OPTIONS_CONTRACT = {
1346
+ canonicalName: exports.TOOL_OPERATION_IDS.integrationsGetOptions,
1347
+ wireNames: exports.TOOL_WIRE_NAMES.integrationsGetOptions,
1348
+ description: "Fetch safe read-only provider options for one workspace integration, such as Pinterest boards, TikTok creator info, locations, Instagram catalogs/products, or YouTube categories.",
1349
+ inputSchema: exports.integrationsGetOptionsInputSchema,
1350
+ wireInputSchemas: {
1351
+ mcp: exports.integrationsGetOptionsMcpInputSchema
1352
+ },
1353
+ outputSchema: mcpStructuredContentOutputSchema,
1354
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.integrationsRead],
1355
+ confirmation: { required: false },
1356
+ idempotency: { required: false },
1357
+ surfaces: {
1358
+ agent: {
1359
+ name: exports.TOOL_WIRE_NAMES.integrationsGetOptions.agent,
1360
+ description: "Fetch live provider options for one connected channel, such as Pinterest boards, TikTok creator info, location search, Instagram catalogs and products, or YouTube video categories. Use an optionKey listed by integrations.get_capabilities; locations require input.query and instagram-products requires input.catalogId. Read-only.",
1361
+ access: "read",
1362
+ gated: false,
1363
+ safeInputSummary: (input) => `integrationId=${input.integrationId} optionKey=${input.optionKey} query=${input.input?.query ? "present" : "absent"}`
1364
+ },
1365
+ mcp: {
1366
+ name: exports.TOOL_WIRE_NAMES.integrationsGetOptions.mcp,
1367
+ title: "Get Integration Options",
1368
+ description: "Fetch safe read-only provider options for one workspace integration, such as Pinterest boards, TikTok creator info, locations, Instagram catalogs/products, or YouTube categories.",
1369
+ scope: "mcp:read",
1370
+ toolsets: integrationInspectionToolsets,
1371
+ annotations: {
1372
+ readOnlyHint: true,
1373
+ destructiveHint: false,
1374
+ idempotentHint: true,
1375
+ openWorldHint: true
1376
+ }
1377
+ }
1378
+ }
1379
+ };
1380
+ exports.TAXONOMY_LIST_CONTRACT = {
1381
+ canonicalName: exports.TOOL_OPERATION_IDS.taxonomyList,
1382
+ wireNames: exports.TOOL_WIRE_NAMES.taxonomyList,
1383
+ description: "List the canonical taxonomy.read catalog: workspace labels, content pillars, and content formats for draft/content planning.",
1384
+ inputSchema: exports.taxonomyListInputSchema,
1385
+ wireInputSchemas: {
1386
+ mcp: exports.taxonomyListMcpInputSchema
1387
+ },
1388
+ outputSchema: exports.taxonomyListOutputSchema,
1389
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.workspaceRead],
1390
+ confirmation: { required: false },
1391
+ idempotency: { required: false },
1392
+ surfaces: {
1393
+ agent: {
1394
+ name: exports.TOOL_WIRE_NAMES.taxonomyList.agent,
1395
+ description: "List workspace labels, content pillars, and content formats in the current workspace. Use it to resolve taxonomy names to IDs for drafting and planning.",
1396
+ access: "read",
1397
+ gated: false,
1398
+ safeInputSummary: (input) => `labelSearch=${input.labelSearch ?? "none"} includeArchived=${input.includeArchived ?? false}`
1399
+ },
1400
+ mcp: {
1401
+ name: exports.TOOL_WIRE_NAMES.taxonomyList.mcp,
1402
+ title: "List Workspace Taxonomy",
1403
+ description: "List the canonical taxonomy.read catalog: workspace labels, content pillars, and content formats for draft/content planning.",
1404
+ scope: "mcp:read",
1405
+ toolsets: contentTaxonomyContextToolsets,
1406
+ annotations: mcpReadAnnotations
1407
+ }
1408
+ }
1409
+ };
1410
+ exports.CAMPAIGNS_LIST_CONTRACT = {
1411
+ canonicalName: exports.TOOL_OPERATION_IDS.campaignsList,
1412
+ wireNames: exports.TOOL_WIRE_NAMES.campaignsList,
1413
+ description: "List first-class workspace campaigns. Campaign status is derived from startDate and endDate, never stored.",
1414
+ inputSchema: exports.campaignsListInputSchema,
1415
+ wireInputSchemas: {
1416
+ mcp: exports.campaignsListMcpInputSchema
1417
+ },
1418
+ outputSchema: exports.campaignsListOutputSchema,
1419
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.workspaceRead],
1420
+ confirmation: { required: false },
1421
+ idempotency: { required: false },
1422
+ surfaces: {
1423
+ agent: {
1424
+ name: exports.TOOL_WIRE_NAMES.campaignsList.agent,
1425
+ description: "List campaigns in the current workspace. Campaign status is derived from startDate and endDate. Use it to resolve campaign names to IDs.",
1426
+ access: "read",
1427
+ gated: false,
1428
+ safeInputSummary: (input) => `search=${input.search ?? "none"} includeArchived=${input.includeArchived ?? false} includePhases=${input.includePhases ?? false}`
1429
+ },
1430
+ mcp: {
1431
+ name: exports.TOOL_WIRE_NAMES.campaignsList.mcp,
1432
+ title: "List Campaigns",
1433
+ description: "List first-class workspace campaigns. Campaign status is derived from startDate and endDate, never stored.",
1434
+ scope: "mcp:read",
1435
+ toolsets: contentSelectionToolsets,
1436
+ annotations: mcpReadAnnotations
1437
+ }
1438
+ }
1439
+ };
1440
+ exports.HASHTAG_GROUPS_LIST_CONTRACT = {
1441
+ canonicalName: exports.TOOL_OPERATION_IDS.hashtagGroupsList,
1442
+ wireNames: exports.TOOL_WIRE_NAMES.hashtagGroupsList,
1443
+ description: "List saved hashtag groups for an Maeve workspace.",
1444
+ inputSchema: exports.hashtagGroupsListInputSchema,
1445
+ wireInputSchemas: {
1446
+ mcp: exports.hashtagGroupsListMcpInputSchema
1447
+ },
1448
+ outputSchema: exports.hashtagGroupsListOutputSchema,
1449
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.workspaceRead],
1450
+ confirmation: { required: false },
1451
+ idempotency: { required: false },
1452
+ surfaces: {
1453
+ agent: {
1454
+ name: exports.TOOL_WIRE_NAMES.hashtagGroupsList.agent,
1455
+ description: "List saved hashtag groups in the current workspace. Use it to resolve hashtag group names to IDs.",
1456
+ access: "read",
1457
+ gated: false,
1458
+ safeInputSummary: () => "current workspace hashtag groups"
1459
+ },
1460
+ mcp: {
1461
+ name: exports.TOOL_WIRE_NAMES.hashtagGroupsList.mcp,
1462
+ title: "List Hashtag Groups",
1463
+ description: "List saved hashtag groups for an Maeve workspace.",
1464
+ scope: "mcp:read",
1465
+ toolsets: contentTaxonomyContextToolsets,
1466
+ annotations: mcpReadAnnotations
1467
+ }
1468
+ }
1469
+ };
1470
+ var mediaTypeSchema = z9.enum(["image", "video", "gif"]);
1471
+ var mediaSelectionToolsets = ["media_selection", "media_room", "media_room_all"];
1472
+ var mediaAuditToolsets = ["media_audit", "media_room", "media_room_all"];
1473
+ exports.mediaListMcpInputSchema = z9.object({
1474
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
1475
+ folderId: z9.string().uuid().optional().describe("Optional folder ID filter."),
1476
+ rootOnly: z9.boolean().optional().describe("Only return media in the root folder."),
1477
+ labelIds: z9.array(z9.string().uuid()).optional().describe("Optional media label IDs filter."),
1478
+ type: mediaTypeSchema.optional().describe("Optional media type filter."),
1479
+ search: z9.string().optional().describe("Optional filename/search filter."),
1480
+ isFavorite: z9.boolean().optional().describe("Optional favorite filter."),
1481
+ isUsed: z9.boolean().optional().describe("Only return media used by content."),
1482
+ isUnused: z9.boolean().optional().describe("Only return media not used by content."),
1483
+ state: z9.enum(["active", "deleted", "all"]).optional().describe("Media lifecycle state. Active excludes Bin items; deleted returns Bin items."),
1484
+ sortBy: z9.enum(["createdAt", "filename", "fileSize"]).optional().describe("Optional sort field."),
1485
+ order: z9.enum(["asc", "desc"]).optional().describe("Optional sort direction."),
1486
+ limit: z9.number().int().min(1).max(100).optional().describe("Page size, default 50, maximum 100."),
1487
+ cursor: z9.string().optional().describe("Optional pagination cursor.")
1488
+ }).strict();
1489
+ exports.mediaListFoldersMcpInputSchema = z9.object({
1490
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
1491
+ parentId: z9.union([z9.string().uuid(), z9.literal("root")]).optional().describe('Optional parent folder ID. Use "root" for root folders.')
1492
+ }).strict();
1493
+ exports.mediaGetFolderMcpInputSchema = z9.object({
1494
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
1495
+ folderId: z9.string().uuid().describe("Media folder ID to inspect.")
1496
+ }).strict();
1497
+ exports.mediaGetFolderPathMcpInputSchema = z9.object({
1498
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
1499
+ folderId: z9.string().uuid().describe("Media folder ID to resolve.")
1500
+ }).strict();
1501
+ exports.mediaListLabelsMcpInputSchema = z9.object({
1502
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
1503
+ search: z9.string().optional().describe("Optional label search filter.")
1504
+ }).strict();
1505
+ exports.mediaGetMcpInputSchema = z9.object({
1506
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
1507
+ mediaId: z9.string().uuid().describe("Media ID to inspect.")
1508
+ }).strict();
1509
+ exports.mediaGetUsageHistoryMcpInputSchema = z9.object({
1510
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
1511
+ mediaId: z9.string().uuid().describe("Media ID to inspect."),
1512
+ limit: z9.number().int().min(1).max(100).optional().describe("Page size. Default 50, maximum 100."),
1513
+ cursor: z9.string().optional().describe("Optional pagination cursor.")
1514
+ }).strict();
1515
+ exports.mediaListInputSchema = z9.object({
1516
+ folderId: z9.string().uuid().optional().describe("Optional folder ID filter."),
1517
+ rootOnly: z9.boolean().optional().describe("Only return media in the root folder."),
1518
+ labelIds: z9.array(z9.string().uuid()).optional().describe("Optional media label IDs filter."),
1519
+ type: mediaTypeSchema.optional().describe("Optional media type filter."),
1520
+ search: z9.string().optional().describe("Optional filename/search filter."),
1521
+ isFavorite: z9.boolean().optional().describe("Optional favorite filter."),
1522
+ isUsed: z9.boolean().optional().describe("Only return media used by content."),
1523
+ isUnused: z9.boolean().optional().describe("Only return media not used by content."),
1524
+ state: z9.enum(["active", "deleted", "all"]).optional().describe("Media lifecycle state. Active excludes Bin items; deleted returns Bin items."),
1525
+ sortBy: z9.enum(["createdAt", "filename", "fileSize"]).optional().describe("Optional sort field."),
1526
+ order: z9.enum(["asc", "desc"]).optional().describe("Optional sort direction."),
1527
+ limit: z9.number().int().min(1).max(100).optional().describe("Page size, default 50, maximum 100."),
1528
+ cursor: z9.string().optional().describe("Optional pagination cursor.")
1529
+ }).strict();
1530
+ exports.mediaListAgentInputSchema = exports.mediaListInputSchema.omit({ limit: true }).extend({
1531
+ limit: z9.number().int().min(1).max(25).default(20).describe("Page size, default 20, maximum 25.")
1532
+ }).strict();
1533
+ exports.mediaListFoldersInputSchema = z9.object({
1534
+ parentId: z9.union([z9.string().uuid(), z9.literal("root")]).optional().describe('Optional parent folder ID. Use "root" for root folders.')
1535
+ }).strict();
1536
+ exports.mediaGetFolderInputSchema = z9.object({
1537
+ folderId: z9.string().uuid().describe("Media folder ID to inspect.")
1538
+ }).strict();
1539
+ exports.mediaGetFolderPathInputSchema = z9.object({
1540
+ folderId: z9.string().uuid().describe("Media folder ID to resolve.")
1541
+ }).strict();
1542
+ exports.mediaListLabelsInputSchema = z9.object({
1543
+ search: z9.string().optional().describe("Optional label search filter.")
1544
+ }).strict();
1545
+ exports.mediaGetInputSchema = z9.object({
1546
+ mediaId: z9.string().uuid().describe("Media ID to inspect.")
1547
+ }).strict();
1548
+ exports.mediaGetUsageHistoryInputSchema = z9.object({
1549
+ mediaId: z9.string().uuid().describe("Media ID to inspect."),
1550
+ limit: z9.number().int().min(1).max(100).optional().describe("Page size. Default 50, maximum 100."),
1551
+ cursor: z9.string().optional().describe("Optional pagination cursor.")
1552
+ }).strict();
1553
+ exports.mediaGetUsageHistoryAgentInputSchema = exports.mediaGetUsageHistoryInputSchema.omit({ limit: true }).extend({
1554
+ limit: z9.number().int().min(1).max(25).default(20).describe("Page size, default 20, maximum 25.")
1555
+ }).strict();
1556
+ exports.MEDIA_LIST_CONTRACT = {
1557
+ canonicalName: exports.TOOL_OPERATION_IDS.mediaList,
1558
+ wireNames: exports.TOOL_WIRE_NAMES.mediaList,
1559
+ description: "List safe media metadata for an Maeve workspace with public API filters.",
1560
+ inputSchema: exports.mediaListInputSchema,
1561
+ wireInputSchemas: {
1562
+ agent: exports.mediaListAgentInputSchema,
1563
+ mcp: exports.mediaListMcpInputSchema
1564
+ },
1565
+ outputSchema: mcpStructuredContentOutputSchema,
1566
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.mediaRead],
1567
+ confirmation: { required: false },
1568
+ idempotency: { required: false },
1569
+ surfaces: {
1570
+ agent: {
1571
+ name: exports.TOOL_WIRE_NAMES.mediaList.agent,
1572
+ description: "List media library items with folder, label, type, favorite, usage, and filename filters plus cursor pagination. Prefer media.search for quick lookups; use this for structured browsing of the library. Read-only.",
1573
+ access: "read",
1574
+ gated: false,
1575
+ safeInputSummary: (input) => `type=${input.type ?? "any"} folderId=${input.folderId ?? "any"} limit=${input.limit ?? 20}`
1576
+ },
1577
+ mcp: {
1578
+ name: exports.TOOL_WIRE_NAMES.mediaList.mcp,
1579
+ title: "List Media",
1580
+ description: "List safe media metadata for an Maeve workspace with public API filters.",
1581
+ scope: "mcp:read",
1582
+ toolsets: mediaSelectionToolsets,
1583
+ annotations: mcpReadAnnotations
1584
+ }
1585
+ }
1586
+ };
1587
+ exports.MEDIA_LIST_FOLDERS_CONTRACT = {
1588
+ canonicalName: exports.TOOL_OPERATION_IDS.mediaListFolders,
1589
+ wireNames: exports.TOOL_WIRE_NAMES.mediaListFolders,
1590
+ description: "List safe media folder metadata for an Maeve workspace.",
1591
+ inputSchema: exports.mediaListFoldersInputSchema,
1592
+ wireInputSchemas: {
1593
+ mcp: exports.mediaListFoldersMcpInputSchema
1594
+ },
1595
+ outputSchema: mcpStructuredContentOutputSchema,
1596
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.mediaRead],
1597
+ confirmation: { required: false },
1598
+ idempotency: { required: false },
1599
+ surfaces: {
1600
+ agent: {
1601
+ name: exports.TOOL_WIRE_NAMES.mediaListFolders.agent,
1602
+ description: 'List media folders under a parent folder (pass parentId "root" for top-level folders) to navigate the media library. Read-only.',
1603
+ access: "read",
1604
+ gated: false,
1605
+ safeInputSummary: (input) => `parentId=${input.parentId ?? "all"}`
1606
+ },
1607
+ mcp: {
1608
+ name: exports.TOOL_WIRE_NAMES.mediaListFolders.mcp,
1609
+ title: "List Media Folders",
1610
+ description: "List safe media folder metadata for an Maeve workspace.",
1611
+ scope: "mcp:read",
1612
+ toolsets: mediaSelectionToolsets,
1613
+ annotations: mcpReadAnnotations
1614
+ }
1615
+ }
1616
+ };
1617
+ exports.MEDIA_GET_FOLDER_CONTRACT = {
1618
+ canonicalName: exports.TOOL_OPERATION_IDS.mediaGetFolder,
1619
+ wireNames: exports.TOOL_WIRE_NAMES.mediaGetFolder,
1620
+ description: "Get safe media folder metadata for an Maeve workspace.",
1621
+ inputSchema: exports.mediaGetFolderInputSchema,
1622
+ wireInputSchemas: {
1623
+ mcp: exports.mediaGetFolderMcpInputSchema
1624
+ },
1625
+ outputSchema: mcpStructuredContentOutputSchema,
1626
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.mediaRead],
1627
+ confirmation: { required: false },
1628
+ idempotency: { required: false },
1629
+ surfaces: {
1630
+ agent: {
1631
+ name: exports.TOOL_WIRE_NAMES.mediaGetFolder.agent,
1632
+ description: "Read metadata for one media folder by folderId. Read-only.",
1633
+ access: "read",
1634
+ gated: false,
1635
+ safeInputSummary: (input) => `folderId=${input.folderId}`
1636
+ },
1637
+ mcp: {
1638
+ name: exports.TOOL_WIRE_NAMES.mediaGetFolder.mcp,
1639
+ title: "Get Media Folder",
1640
+ description: "Get safe media folder metadata for an Maeve workspace.",
1641
+ scope: "mcp:read",
1642
+ toolsets: mediaSelectionToolsets,
1643
+ annotations: mcpReadAnnotations
1644
+ }
1645
+ }
1646
+ };
1647
+ exports.MEDIA_GET_FOLDER_PATH_CONTRACT = {
1648
+ canonicalName: exports.TOOL_OPERATION_IDS.mediaGetFolderPath,
1649
+ wireNames: exports.TOOL_WIRE_NAMES.mediaGetFolderPath,
1650
+ description: "Get the safe ancestor path for an Maeve media folder.",
1651
+ inputSchema: exports.mediaGetFolderPathInputSchema,
1652
+ wireInputSchemas: {
1653
+ mcp: exports.mediaGetFolderPathMcpInputSchema
1654
+ },
1655
+ outputSchema: mcpStructuredContentOutputSchema,
1656
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.mediaRead],
1657
+ confirmation: { required: false },
1658
+ idempotency: { required: false },
1659
+ surfaces: {
1660
+ agent: {
1661
+ name: exports.TOOL_WIRE_NAMES.mediaGetFolderPath.agent,
1662
+ description: "Resolve the ancestor folder path for one media folder, from root down to the folder itself. Read-only.",
1663
+ access: "read",
1664
+ gated: false,
1665
+ safeInputSummary: (input) => `folderId=${input.folderId}`
1666
+ },
1667
+ mcp: {
1668
+ name: exports.TOOL_WIRE_NAMES.mediaGetFolderPath.mcp,
1669
+ title: "Get Media Folder Path",
1670
+ description: "Get the safe ancestor path for an Maeve media folder.",
1671
+ scope: "mcp:read",
1672
+ toolsets: mediaSelectionToolsets,
1673
+ annotations: mcpReadAnnotations
1674
+ }
1675
+ }
1676
+ };
1677
+ exports.MEDIA_LIST_LABELS_CONTRACT = {
1678
+ canonicalName: exports.TOOL_OPERATION_IDS.mediaListLabels,
1679
+ wireNames: exports.TOOL_WIRE_NAMES.mediaListLabels,
1680
+ description: "List workspace labels through the media.read compatibility surface for Media Room workflows. Use list_taxonomy for the canonical taxonomy.read catalog.",
1681
+ inputSchema: exports.mediaListLabelsInputSchema,
1682
+ wireInputSchemas: {
1683
+ mcp: exports.mediaListLabelsMcpInputSchema
1684
+ },
1685
+ outputSchema: mcpStructuredContentOutputSchema,
1686
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.mediaRead],
1687
+ confirmation: { required: false },
1688
+ idempotency: { required: false },
1689
+ surfaces: {
1690
+ agent: {
1691
+ name: exports.TOOL_WIRE_NAMES.mediaListLabels.agent,
1692
+ description: "List media labels for the workspace, optionally filtered by a search string. Prefer taxonomy.list for the canonical label catalog; use this when working inside the media library. Read-only.",
1693
+ access: "read",
1694
+ gated: false,
1695
+ safeInputSummary: (input) => `search=${input.search ?? "none"}`
1696
+ },
1697
+ mcp: {
1698
+ name: exports.TOOL_WIRE_NAMES.mediaListLabels.mcp,
1699
+ title: "List Workspace Labels For Media",
1700
+ description: "List workspace labels through the media.read compatibility surface for Media Room workflows. Use list_taxonomy for the canonical taxonomy.read catalog.",
1701
+ scope: "mcp:read",
1702
+ toolsets: mediaSelectionToolsets,
1703
+ annotations: mcpReadAnnotations
1704
+ }
1705
+ }
1706
+ };
1707
+ exports.MEDIA_GET_CONTRACT = {
1708
+ canonicalName: exports.TOOL_OPERATION_IDS.mediaGet,
1709
+ wireNames: exports.TOOL_WIRE_NAMES.mediaGet,
1710
+ description: "Get safe media metadata for a workspace media asset.",
1711
+ inputSchema: exports.mediaGetInputSchema,
1712
+ wireInputSchemas: {
1713
+ mcp: exports.mediaGetMcpInputSchema
1714
+ },
1715
+ outputSchema: mcpStructuredContentOutputSchema,
1716
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.mediaRead],
1717
+ confirmation: { required: false },
1718
+ idempotency: { required: false },
1719
+ surfaces: {
1720
+ agent: {
1721
+ name: exports.TOOL_WIRE_NAMES.mediaGet.agent,
1722
+ description: "Read full sanitized metadata for one media item by mediaId (filename, type, dimensions, alt text, folder, labels, usage flags). This returns metadata only; the agent cannot view the image or video itself. Read-only.",
1723
+ access: "read",
1724
+ gated: false,
1725
+ safeInputSummary: (input) => `mediaId=${input.mediaId}`
1726
+ },
1727
+ mcp: {
1728
+ name: exports.TOOL_WIRE_NAMES.mediaGet.mcp,
1729
+ title: "Get Media",
1730
+ description: "Get safe media metadata for a workspace media asset.",
1731
+ scope: "mcp:read",
1732
+ toolsets: mediaSelectionToolsets,
1733
+ annotations: mcpReadAnnotations
1734
+ }
1735
+ }
1736
+ };
1737
+ exports.MEDIA_GET_USAGE_HISTORY_CONTRACT = {
1738
+ canonicalName: exports.TOOL_OPERATION_IDS.mediaGetUsageHistory,
1739
+ wireNames: exports.TOOL_WIRE_NAMES.mediaGetUsageHistory,
1740
+ description: "Get safe usage history for a single Media Room asset.",
1741
+ inputSchema: exports.mediaGetUsageHistoryInputSchema,
1742
+ wireInputSchemas: {
1743
+ agent: exports.mediaGetUsageHistoryAgentInputSchema,
1744
+ mcp: exports.mediaGetUsageHistoryMcpInputSchema
1745
+ },
1746
+ outputSchema: mcpStructuredContentOutputSchema,
1747
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.mediaRead],
1748
+ confirmation: { required: false },
1749
+ idempotency: { required: false },
1750
+ surfaces: {
1751
+ agent: {
1752
+ name: exports.TOOL_WIRE_NAMES.mediaGetUsageHistory.agent,
1753
+ description: "Read where one media item has been used (the content it was attached to), newest first. Useful to avoid reposting the same asset. Read-only.",
1754
+ access: "read",
1755
+ gated: false,
1756
+ safeInputSummary: (input) => `mediaId=${input.mediaId} limit=${input.limit ?? 20}`
1757
+ },
1758
+ mcp: {
1759
+ name: exports.TOOL_WIRE_NAMES.mediaGetUsageHistory.mcp,
1760
+ title: "Get Media Usage History",
1761
+ description: "Get safe usage history for a single Media Room asset.",
1762
+ scope: "mcp:read",
1763
+ toolsets: mediaAuditToolsets,
1764
+ annotations: mcpReadAnnotations
1765
+ }
1766
+ }
1767
+ };
1768
+ var analyticsDaysSchema = z9.union([z9.number().int().min(1).max(90), z9.literal("all")]);
1769
+ var analyticsPostSortFields = ["recent", "engagement", "views"];
1770
+ var analyticsOverviewToolsets = ["analytics_overview", "analytics_read_only"];
1771
+ var analyticsPostsToolsets = ["analytics_posts", "analytics_read_only"];
1772
+ exports.analyticsAggregateMcpInputSchema = z9.object({
1773
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
1774
+ integrationIds: z9.array(z9.string().uuid()).max(20).optional().describe("Optional integration IDs to include. Empty returns no metrics."),
1775
+ days: analyticsDaysSchema.optional().describe('Analytics window, either an integer between 1 and 90 or "all". Default 30.')
1776
+ }).strict();
1777
+ exports.analyticsIntegrationMcpInputSchema = z9.object({
1778
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
1779
+ integrationId: z9.string().uuid().describe("Integration ID to inspect.")
1780
+ }).strict();
1781
+ exports.analyticsPostsMcpInputSchema = z9.object({
1782
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
1783
+ integrationId: z9.string().uuid().optional().describe("Single integration ID to inspect."),
1784
+ integrationIds: z9.array(z9.string().uuid()).max(20).optional().describe("Integration IDs for aggregated post analytics. Used when integrationId is omitted."),
1785
+ limit: z9.number().int().min(1).max(50).optional().describe("Page size. Default 10 single, 12 aggregate."),
1786
+ offset: z9.number().int().min(0).optional().describe("Offset for pagination."),
1787
+ days: analyticsDaysSchema.optional().describe("Aggregate analytics window. Default 30."),
1788
+ sortBy: z9.enum(analyticsPostSortFields).optional().describe("Aggregate sort. Default recent.")
1789
+ }).strict();
1790
+ exports.analyticsPostsAggregateMcpInputSchema = z9.object({
1791
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
1792
+ integrationIds: z9.array(z9.string().uuid()).max(20).optional().describe("Optional integration IDs to include. Empty returns no posts."),
1793
+ limit: z9.number().int().min(1).max(50).optional().describe("Page size. Default 12."),
1794
+ offset: z9.number().int().min(0).optional().describe("Offset for pagination. Default 0."),
1795
+ days: analyticsDaysSchema.optional().describe('Analytics window, either an integer between 1 and 90 or "all". Default 30.'),
1796
+ sortBy: z9.enum(analyticsPostSortFields).optional().describe("Sort field. Default recent.")
1797
+ }).strict();
1798
+ exports.analyticsPostsAggregateInputSchema = z9.object({
1799
+ integrationIds: z9.array(z9.string().uuid()).max(20).optional().describe("Optional integration IDs to include. Empty returns no posts."),
1800
+ limit: z9.number().int().min(1).max(50).optional().describe("Page size. Default 12."),
1801
+ offset: z9.number().int().min(0).optional().describe("Offset for pagination. Default 0."),
1802
+ days: analyticsDaysSchema.optional().describe('Analytics window, either an integer between 1 and 90 or "all". Default 30.'),
1803
+ sortBy: z9.enum(analyticsPostSortFields).optional().describe("Sort field. Default recent.")
1804
+ }).strict();
1805
+ exports.postAnalyticsMcpInputSchema = z9.object({
1806
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
1807
+ contentId: z9.string().uuid().describe("Published content ID.")
1808
+ }).strict();
1809
+ exports.analyticsAggregateInputSchema = z9.object({
1810
+ integrationIds: z9.array(z9.string().uuid()).max(20).optional().describe("Optional integration IDs to include. Empty returns no metrics."),
1811
+ days: analyticsDaysSchema.optional().describe('Analytics window, either an integer between 1 and 90 or "all". Default 30.')
1812
+ }).strict();
1813
+ exports.analyticsAggregateAgentInputSchema = z9.object({
1814
+ integrationIds: z9.array(z9.string().uuid()).max(20).optional().describe("Integration IDs for the connected channels to include. Empty returns no metrics."),
1815
+ days: z9.number().int().min(1).max(90).optional().describe("Analytics window in days, between 1 and 90. Default 30.")
1816
+ }).strict();
1817
+ exports.analyticsIntegrationInputSchema = z9.object({
1818
+ integrationId: z9.string().uuid().describe("Integration ID to inspect.")
1819
+ }).strict();
1820
+ exports.analyticsPostsInputSchema = z9.object({
1821
+ integrationId: z9.string().uuid().optional().describe("Single integration ID to inspect."),
1822
+ integrationIds: z9.array(z9.string().uuid()).max(20).optional().describe("Integration IDs for aggregated post analytics. Used when integrationId is omitted."),
1823
+ limit: z9.number().int().min(1).max(50).optional().describe("Page size. Default 10 single, 12 aggregate."),
1824
+ offset: z9.number().int().min(0).optional().describe("Offset for pagination."),
1825
+ days: analyticsDaysSchema.optional().describe("Aggregate analytics window. Default 30."),
1826
+ sortBy: z9.enum(analyticsPostSortFields).optional().describe("Aggregate sort. Default recent.")
1827
+ }).strict();
1828
+ exports.analyticsPostsAgentInputSchema = z9.object({
1829
+ integrationId: z9.string().uuid().optional().describe("Single integration ID to inspect."),
1830
+ integrationIds: z9.array(z9.string().uuid()).max(20).optional().describe("Integration IDs for aggregated post analytics. Used when integrationId is omitted."),
1831
+ limit: z9.number().int().min(1).max(20).optional().describe("Page size, maximum 20. Default 10 single, 12 aggregate."),
1832
+ offset: z9.number().int().min(0).optional().describe("Offset for pagination."),
1833
+ days: z9.number().int().min(1).max(90).optional().describe("Analytics window in days, between 1 and 90. Default 30."),
1834
+ sortBy: z9.enum(analyticsPostSortFields).optional().describe("Aggregate sort. Default recent.")
1835
+ }).strict();
1836
+ exports.postAnalyticsInputSchema = z9.object({
1837
+ contentId: z9.string().uuid().describe("Published content ID.")
1838
+ }).strict();
1839
+ exports.ANALYTICS_GET_SUMMARY_CONTRACT = {
1840
+ canonicalName: exports.TOOL_OPERATION_IDS.analyticsGetSummary,
1841
+ wireNames: exports.TOOL_WIRE_NAMES.analyticsGetSummary,
1842
+ description: "Compatibility summary alias for safe aggregated analytics metrics. Returns metrics under an analytics key and does not generate reports or files.",
1843
+ inputSchema: exports.analyticsAggregateInputSchema,
1844
+ wireInputSchemas: {
1845
+ agent: exports.analyticsAggregateAgentInputSchema,
1846
+ mcp: exports.analyticsAggregateMcpInputSchema
1847
+ },
1848
+ outputSchema: mcpStructuredContentOutputSchema,
1849
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.analyticsRead],
1850
+ confirmation: { required: false },
1851
+ idempotency: { required: false },
1852
+ surfaces: {
1853
+ agent: {
1854
+ name: exports.TOOL_WIRE_NAMES.analyticsGetSummary.agent,
1855
+ description: "Read an aggregated account analytics summary (metrics nested under an analytics key) for selected connected channels. Prefer analytics.get_aggregate for the same data unnested. Pass integrationIds from Workspace context; an omitted or empty list returns no metrics. Read-only.",
1856
+ access: "read",
1857
+ gated: false,
1858
+ safeInputSummary: (input) => `integrationIds=${input.integrationIds?.length ?? "none"} days=${input.days ?? 30}`
1859
+ },
1860
+ mcp: {
1861
+ name: exports.TOOL_WIRE_NAMES.analyticsGetSummary.mcp,
1862
+ title: "Get Analytics Summary",
1863
+ description: "Compatibility summary alias for safe aggregated analytics metrics. Returns metrics under an analytics key and does not generate reports or files.",
1864
+ scope: "mcp:read",
1865
+ toolsets: analyticsOverviewToolsets,
1866
+ annotations: mcpReadAnnotations
1867
+ }
1868
+ }
1869
+ };
1870
+ exports.ANALYTICS_GET_AGGREGATE_CONTRACT = {
1871
+ canonicalName: exports.TOOL_OPERATION_IDS.analyticsGetAggregate,
1872
+ wireNames: exports.TOOL_WIRE_NAMES.analyticsGetAggregate,
1873
+ description: "Canonical MCP read for safe aggregated analytics metrics across selected integrations. Does not generate reports or files.",
1874
+ inputSchema: exports.analyticsAggregateInputSchema,
1875
+ wireInputSchemas: {
1876
+ agent: exports.analyticsAggregateAgentInputSchema,
1877
+ mcp: exports.analyticsAggregateMcpInputSchema
1878
+ },
1879
+ outputSchema: mcpStructuredContentOutputSchema,
1880
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.analyticsRead],
1881
+ confirmation: { required: false },
1882
+ idempotency: { required: false },
1883
+ surfaces: {
1884
+ agent: {
1885
+ name: exports.TOOL_WIRE_NAMES.analyticsGetAggregate.agent,
1886
+ description: "Read aggregated account analytics metrics (audience, reach, engagement, views) across the workspace's connected channels for a window of up to 90 days. Pass integrationIds from Workspace context; an omitted or empty list returns no metrics. Use to ground performance answers in real account-level numbers. Read-only.",
1887
+ access: "read",
1888
+ gated: false,
1889
+ safeInputSummary: (input) => `integrationIds=${input.integrationIds?.length ?? "none"} days=${input.days ?? 30}`
1890
+ },
1891
+ mcp: {
1892
+ name: exports.TOOL_WIRE_NAMES.analyticsGetAggregate.mcp,
1893
+ title: "Get Aggregated Analytics",
1894
+ description: "Canonical MCP read for safe aggregated analytics metrics across selected integrations. Does not generate reports or files.",
1895
+ scope: "mcp:read",
1896
+ toolsets: analyticsOverviewToolsets,
1897
+ annotations: mcpReadAnnotations
1898
+ }
1899
+ }
1900
+ };
1901
+ exports.ANALYTICS_GET_HEALTH_CONTRACT = {
1902
+ canonicalName: exports.TOOL_OPERATION_IDS.analyticsGetHealth,
1903
+ wireNames: exports.TOOL_WIRE_NAMES.analyticsGetHealth,
1904
+ description: "Get sanitized analytics health for one connected social integration.",
1905
+ inputSchema: exports.analyticsIntegrationInputSchema,
1906
+ wireInputSchemas: {
1907
+ mcp: exports.analyticsIntegrationMcpInputSchema
1908
+ },
1909
+ outputSchema: mcpStructuredContentOutputSchema,
1910
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.analyticsRead],
1911
+ confirmation: { required: false },
1912
+ idempotency: { required: false },
1913
+ surfaces: {
1914
+ agent: {
1915
+ name: exports.TOOL_WIRE_NAMES.analyticsGetHealth.agent,
1916
+ description: "Check analytics sync health for one connected channel: sync status, last successful fetch, and any reconnect or capability warnings. Use it before treating missing analytics as a data gap. Read-only.",
1917
+ access: "read",
1918
+ gated: false,
1919
+ safeInputSummary: (input) => `integrationId=${input.integrationId}`
1920
+ },
1921
+ mcp: {
1922
+ name: exports.TOOL_WIRE_NAMES.analyticsGetHealth.mcp,
1923
+ title: "Get Analytics Health",
1924
+ description: "Get sanitized analytics health for one connected social integration.",
1925
+ scope: "mcp:read",
1926
+ toolsets: analyticsOverviewToolsets,
1927
+ annotations: mcpReadAnnotations
1928
+ }
1929
+ }
1930
+ };
1931
+ exports.ANALYTICS_GET_DEMOGRAPHICS_CONTRACT = {
1932
+ canonicalName: exports.TOOL_OPERATION_IDS.analyticsGetDemographics,
1933
+ wireNames: exports.TOOL_WIRE_NAMES.analyticsGetDemographics,
1934
+ description: "Get sanitized audience demographics for one connected social integration.",
1935
+ inputSchema: exports.analyticsIntegrationInputSchema,
1936
+ wireInputSchemas: {
1937
+ mcp: exports.analyticsIntegrationMcpInputSchema
1938
+ },
1939
+ outputSchema: mcpStructuredContentOutputSchema,
1940
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.analyticsRead],
1941
+ confirmation: { required: false },
1942
+ idempotency: { required: false },
1943
+ surfaces: {
1944
+ agent: {
1945
+ name: exports.TOOL_WIRE_NAMES.analyticsGetDemographics.agent,
1946
+ description: "Read audience demographics (age, gender, and location breakdowns where the platform provides them) for one connected channel. Use to ground audience claims; never invent demographics. Read-only.",
1947
+ access: "read",
1948
+ gated: false,
1949
+ safeInputSummary: (input) => `integrationId=${input.integrationId}`
1950
+ },
1951
+ mcp: {
1952
+ name: exports.TOOL_WIRE_NAMES.analyticsGetDemographics.mcp,
1953
+ title: "Get Analytics Demographics",
1954
+ description: "Get sanitized audience demographics for one connected social integration.",
1955
+ scope: "mcp:read",
1956
+ toolsets: analyticsOverviewToolsets,
1957
+ annotations: mcpReadAnnotations
1958
+ }
1959
+ }
1960
+ };
1961
+ exports.ANALYTICS_GET_POSTS_CONTRACT = {
1962
+ canonicalName: exports.TOOL_OPERATION_IDS.analyticsGetPosts,
1963
+ wireNames: exports.TOOL_WIRE_NAMES.analyticsGetPosts,
1964
+ description: "Compatibility MCP read for sanitized post analytics. Use integrationId for one account or integrationIds for aggregate posts.",
1965
+ inputSchema: exports.analyticsPostsInputSchema,
1966
+ wireInputSchemas: {
1967
+ agent: exports.analyticsPostsAgentInputSchema,
1968
+ mcp: exports.analyticsPostsMcpInputSchema
1969
+ },
1970
+ outputSchema: mcpStructuredContentOutputSchema,
1971
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.analyticsRead],
1972
+ confirmation: { required: false },
1973
+ idempotency: { required: false },
1974
+ surfaces: {
1975
+ agent: {
1976
+ name: exports.TOOL_WIRE_NAMES.analyticsGetPosts.agent,
1977
+ description: "Read sanitized per-post analytics for one channel (integrationId) or several (integrationIds). Prefer analytics.get_posts_aggregate for cross-channel post performance; use this when you need a single channel or offset pagination. Keep limit small. Read-only.",
1978
+ access: "read",
1979
+ gated: false,
1980
+ safeInputSummary: (input) => `integrationId=${input.integrationId ?? "none"} integrationIds=${input.integrationIds?.length ?? "none"} days=${input.days ?? 30} limit=${input.limit ?? "default"}`
1981
+ },
1982
+ mcp: {
1983
+ name: exports.TOOL_WIRE_NAMES.analyticsGetPosts.mcp,
1984
+ title: "Get Analytics Posts",
1985
+ description: "Compatibility MCP read for sanitized post analytics. Use integrationId for one account or integrationIds for aggregate posts.",
1986
+ scope: "mcp:read",
1987
+ toolsets: analyticsPostsToolsets,
1988
+ annotations: mcpReadAnnotations
1989
+ }
1990
+ }
1991
+ };
1992
+ exports.ANALYTICS_GET_POSTS_AGGREGATE_CONTRACT = {
1993
+ canonicalName: exports.TOOL_OPERATION_IDS.analyticsGetPostsAggregate,
1994
+ wireNames: exports.TOOL_WIRE_NAMES.analyticsGetPostsAggregate,
1995
+ description: "Canonical MCP read for sanitized aggregate post analytics across selected integrations in an Maeve workspace.",
1996
+ inputSchema: exports.analyticsPostsAggregateInputSchema,
1997
+ wireInputSchemas: {
1998
+ mcp: exports.analyticsPostsAggregateMcpInputSchema
1999
+ },
2000
+ outputSchema: mcpStructuredContentOutputSchema,
2001
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.analyticsRead],
2002
+ confirmation: {
2003
+ required: false
2004
+ },
2005
+ idempotency: {
2006
+ required: false
2007
+ },
2008
+ surfaces: {
2009
+ agent: {
2010
+ name: exports.TOOL_WIRE_NAMES.analyticsGetPostsAggregate.agent,
2011
+ description: "Read recent post performance analytics across the workspace's connected accounts. Read-only; use to ground performance references before drafting. Pass integrationIds for the connected channels to include (integrationId values are listed in Workspace context); an omitted or empty list returns no posts.",
2012
+ access: "read",
2013
+ gated: false,
2014
+ safeInputSummary: (input) => `integrationIds=${input.integrationIds?.length ?? "none"} days=${input.days ?? 30} sortBy=${input.sortBy ?? "recent"} limit=${input.limit ?? 12}`
2015
+ },
2016
+ mcp: {
2017
+ name: exports.TOOL_WIRE_NAMES.analyticsGetPostsAggregate.mcp,
2018
+ title: "Get Aggregated Analytics Posts",
2019
+ description: "Canonical MCP read for sanitized aggregate post analytics across selected integrations in an Maeve workspace.",
2020
+ scope: "mcp:read",
2021
+ toolsets: analyticsPostsToolsets,
2022
+ annotations: mcpReadAnnotations
2023
+ }
2024
+ }
2025
+ };
2026
+ exports.ANALYTICS_GET_POST_CONTRACT = {
2027
+ canonicalName: exports.TOOL_OPERATION_IDS.analyticsGetPost,
2028
+ wireNames: exports.TOOL_WIRE_NAMES.analyticsGetPost,
2029
+ description: "Get sanitized analytics for a single published Maeve content item.",
2030
+ inputSchema: exports.postAnalyticsInputSchema,
2031
+ wireInputSchemas: {
2032
+ mcp: exports.postAnalyticsMcpInputSchema
2033
+ },
2034
+ outputSchema: mcpStructuredContentOutputSchema,
2035
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.analyticsRead],
2036
+ confirmation: { required: false },
2037
+ idempotency: { required: false },
2038
+ surfaces: {
2039
+ agent: {
2040
+ name: exports.TOOL_WIRE_NAMES.analyticsGetPost.agent,
2041
+ description: "Read analytics for one published content item by contentId (impressions, reach, likes, comments, shares, saves). Only works for content that has actually published. Read-only.",
2042
+ access: "read",
2043
+ gated: false,
2044
+ safeInputSummary: (input) => `contentId=${input.contentId}`
2045
+ },
2046
+ mcp: {
2047
+ name: exports.TOOL_WIRE_NAMES.analyticsGetPost.mcp,
2048
+ title: "Get Post Analytics",
2049
+ description: "Get sanitized analytics for a single published Maeve content item.",
2050
+ scope: "mcp:read",
2051
+ toolsets: analyticsPostsToolsets,
2052
+ annotations: mcpReadAnnotations
2053
+ }
2054
+ }
2055
+ };
2056
+ var PUBLIC_CONTENT_POST_TYPE_VALUES = ["post", "reel", "story", "thread", "poll"];
2057
+ var WORKBENCH_PRIORITY_VALUES = ["urgent", "high", "medium", "low"];
2058
+ var LINKEDIN_POLL_DURATION_VALUES = ["ONE_DAY", "THREE_DAYS", "SEVEN_DAYS", "FOURTEEN_DAYS"];
2059
+ var LINKEDIN_POLL_VOTE_SELECTION_TYPE_VALUES = ["SINGLE_VOTE"];
2060
+ var FACEBOOK_PAGE_POST_CTA_TYPES = [
2061
+ "LEARN_MORE",
2062
+ "SIGN_UP",
2063
+ "DOWNLOAD",
2064
+ "WATCH_MORE",
2065
+ "BOOK_TRAVEL",
2066
+ "LISTEN_MUSIC",
2067
+ "USE_APP",
2068
+ "INSTALL_APP",
2069
+ "NO_BUTTON"
2070
+ ];
2071
+ var THREADS_REPLY_CONTROL_VALUES = [
2072
+ "everyone",
2073
+ "accounts_you_follow",
2074
+ "mentioned_only",
2075
+ "parent_post_author_only",
2076
+ "followers_only"
2077
+ ];
2078
+ var FACEBOOK_PAGE_SETTINGS_FIELDS = [
2079
+ { key: "facebookLinkUrl", type: "string" },
2080
+ { key: "facebookCtaType", type: "string", enum: FACEBOOK_PAGE_POST_CTA_TYPES },
2081
+ { key: "facebookLocationId", type: "string" }
2082
+ ];
2083
+ var CREATE_DRAFT_PROVIDER_SETTINGS_FIELDS_BY_PLATFORM = {
2084
+ instagram: [
2085
+ { key: "collaborators", type: "string[]" },
2086
+ { key: "locationId", type: "string" },
2087
+ { key: "audio_id", type: "string" },
2088
+ { key: "audio_volume", type: "number", min: 0, max: 100 },
2089
+ { key: "video_volume", type: "number", min: 0, max: 100 }
2090
+ ],
2091
+ facebook: FACEBOOK_PAGE_SETTINGS_FIELDS,
2092
+ "facebook-page": FACEBOOK_PAGE_SETTINGS_FIELDS,
2093
+ linkedin: [],
2094
+ "linkedin-page": [],
2095
+ x: [{ key: "xCommunityUrl", type: "string" }],
2096
+ threads: [
2097
+ { key: "topicTag", type: "string" },
2098
+ { key: "linkAttachment", type: "string" },
2099
+ { key: "isGhostPost", type: "boolean" },
2100
+ { key: "locationId", type: "string" },
2101
+ { key: "replyControl", type: "string", enum: THREADS_REPLY_CONTROL_VALUES }
2102
+ ],
2103
+ tiktok: [
2104
+ { key: "privacy_level", type: "string" },
2105
+ { key: "disable_comment", type: "boolean" },
2106
+ { key: "disable_duet", type: "boolean" },
2107
+ { key: "disable_stitch", type: "boolean" },
2108
+ { key: "brand_content_toggle", type: "boolean" },
2109
+ { key: "brand_organic_toggle", type: "boolean" },
2110
+ { key: "is_aigc", type: "boolean" },
2111
+ { key: "tiktok_post_to_drafts", type: "boolean" },
2112
+ { key: "photo_cover_index", type: "number" },
2113
+ { key: "auto_add_music", type: "boolean" }
2114
+ ],
2115
+ youtube: [
2116
+ { key: "privacyStatus", type: "string", enum: ["public", "unlisted", "private"] },
2117
+ { key: "categoryId", type: "string" },
2118
+ { key: "tags", type: "string[]" },
2119
+ { key: "madeForKids", type: "boolean" },
2120
+ { key: "notifySubscribers", type: "boolean" },
2121
+ { key: "embeddable", type: "boolean" },
2122
+ { key: "license", type: "string", enum: ["youtube", "creativeCommon"] }
2123
+ ],
2124
+ pinterest: [
2125
+ { key: "boardId", type: "string" },
2126
+ { key: "link", type: "string" },
2127
+ { key: "altText", type: "string" }
2128
+ ]
2129
+ };
2130
+ function createDraftProviderSettingsZodSchema() {
2131
+ const shape = {};
2132
+ const fieldsByKey = /* @__PURE__ */ new Map();
2133
+ for (const fields of Object.values(CREATE_DRAFT_PROVIDER_SETTINGS_FIELDS_BY_PLATFORM)) {
2134
+ for (const field of fields) {
2135
+ fieldsByKey.set(field.key, field);
2136
+ }
2137
+ }
2138
+ for (const field of fieldsByKey.values()) {
2139
+ shape[field.key] = createDraftProviderSettingZodField(field).optional();
2140
+ }
2141
+ return z9.object(shape).strict();
2142
+ }
2143
+ function createDraftProviderSettingZodField(field) {
2144
+ if (field.enum?.length) {
2145
+ return z9.enum(field.enum);
2146
+ }
2147
+ if (field.type === "string")
2148
+ return z9.string();
2149
+ if (field.type === "string[]")
2150
+ return z9.array(z9.string());
2151
+ if (field.type === "boolean")
2152
+ return z9.boolean();
2153
+ let schema = z9.number();
2154
+ if (field.min !== void 0)
2155
+ schema = schema.min(field.min);
2156
+ if (field.max !== void 0)
2157
+ schema = schema.max(field.max);
2158
+ return schema;
2159
+ }
2160
+ var createDraftContentSettingsSchema = createDraftProviderSettingsZodSchema();
2161
+ var createDraftContentMediaSchema = z9.array(z9.object({
2162
+ mediaId: z9.string().uuid(),
2163
+ order: z9.number().int().min(0).optional(),
2164
+ crops: z9.record(z9.string(), z9.unknown()).optional(),
2165
+ userTags: z9.array(z9.unknown()).optional(),
2166
+ productTags: z9.array(z9.unknown()).optional(),
2167
+ cover: z9.record(z9.string(), z9.unknown()).nullable().optional()
2168
+ })).max(10);
2169
+ var createDraftCaptionsObjectSchema = z9.object({
2170
+ canonical: z9.string().max(25e3).nullable().optional(),
2171
+ overrides: z9.record(z9.string(), z9.string().max(25e3))
2172
+ });
2173
+ var createDraftCaptionsSchema = createDraftCaptionsObjectSchema.optional();
2174
+ var createDraftLinkedinPollSchema = z9.object({
2175
+ question: z9.string().min(1).max(140),
2176
+ options: z9.array(z9.object({ text: z9.string().min(1).max(30) })).min(2).max(4),
2177
+ duration: z9.enum(LINKEDIN_POLL_DURATION_VALUES),
2178
+ voteSelectionType: z9.enum(LINKEDIN_POLL_VOTE_SELECTION_TYPE_VALUES).optional(),
2179
+ isVoterVisibleToAuthor: z9.boolean().optional()
2180
+ }).strict();
2181
+ var createDraftContentInputShape = {
2182
+ idempotencyKey: z9.string().max(255).optional().describe("Optional create idempotency key. Generated and returned when omitted."),
2183
+ integrationId: z9.string().uuid().describe("Target social integration ID."),
2184
+ internalTitle: z9.string().max(500).nullable().optional().describe("Optional internal planning title. Never published."),
2185
+ publishTitle: z9.string().max(500).nullable().optional().describe("Optional provider-facing title for platforms that support or require one."),
2186
+ notes: z9.string().max(1e5).optional().describe("Optional rich-text notes (HTML) attached to the content. Internal - never published."),
2187
+ captions: createDraftCaptionsSchema.describe("Optional canonical and platform caption overrides. When provided, use captions: { canonical, overrides: {} }."),
2188
+ contentMedia: createDraftContentMediaSchema.optional().describe("Canonical media relationship input with per-content crops, tags, ordering, and cover metadata."),
2189
+ poll: createDraftLinkedinPollSchema.nullable().optional().describe("LinkedIn poll content. Required when postType is poll."),
2190
+ settings: createDraftContentSettingsSchema.optional().describe("Optional strict platform-specific provider settings."),
2191
+ postType: z9.enum(PUBLIC_CONTENT_POST_TYPE_VALUES).optional().describe("Optional platform post type."),
2192
+ firstComment: z9.string().optional().describe("Optional first comment text."),
2193
+ shareToFeed: z9.boolean().optional().describe("Optional feed-sharing setting."),
2194
+ pillarIds: z9.array(z9.string().uuid()).optional().describe("Optional content pillar IDs."),
2195
+ formatIds: z9.array(z9.string().uuid()).optional().describe("Optional content format IDs."),
2196
+ campaignId: z9.string().uuid().nullable().optional().describe("Optional campaign ID."),
2197
+ campaignPhaseId: z9.string().uuid().nullable().optional().describe("Optional campaign phase ID."),
2198
+ labelIds: z9.array(z9.string().uuid()).optional().describe("Optional taxonomy label IDs."),
2199
+ priority: z9.enum(WORKBENCH_PRIORITY_VALUES).optional().describe("Optional workbench priority."),
2200
+ assigneeIds: z9.array(z9.string().uuid()).optional().describe("Optional assignee user IDs."),
2201
+ threadMessages: z9.array(z9.object({
2202
+ captions: createDraftCaptionsObjectSchema,
2203
+ contentMedia: createDraftContentMediaSchema.optional()
2204
+ })).max(20).optional().describe("Optional thread/reply draft messages with canonical captions and media relationships.")
2205
+ };
2206
+ exports.createDraftContentInputSchema = z9.object(createDraftContentInputShape).strict();
2207
+ exports.createDraftContentMcpInputSchema = z9.object({
2208
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
2209
+ ...createDraftContentInputShape
2210
+ }).strict();
2211
+ exports.createDraftContentOutputSchema = z9.object({
2212
+ ok: z9.literal(true),
2213
+ renderHint: z9.literal("draft_created"),
2214
+ content: z9.object({
2215
+ contentId: z9.string(),
2216
+ status: z9.string(),
2217
+ title: z9.string().nullable(),
2218
+ integrationId: z9.string(),
2219
+ platform: z9.string().nullable(),
2220
+ accountLabel: z9.string().nullable(),
2221
+ groupId: z9.string().optional(),
2222
+ contentIds: z9.array(z9.string()).optional()
2223
+ }).strict(),
2224
+ idempotency: z9.object({
2225
+ key: z9.string(),
2226
+ replayed: z9.boolean()
2227
+ }).strict()
2228
+ }).strict();
2229
+ exports.CONTENT_CREATE_DRAFT_CONTRACT = {
2230
+ canonicalName: exports.TOOL_OPERATION_IDS.contentCreateDraft,
2231
+ wireNames: exports.TOOL_WIRE_NAMES.contentCreateDraft,
2232
+ description: "Create Maeve content as a saved draft only. Does not schedule or publish, and requires explicit user confirmation on agent surfaces.",
2233
+ inputSchema: exports.createDraftContentInputSchema,
2234
+ wireInputSchemas: {
2235
+ mcp: exports.createDraftContentMcpInputSchema
2236
+ },
2237
+ outputSchema: exports.createDraftContentOutputSchema,
2238
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.contentDraftCreate],
2239
+ confirmation: {
2240
+ required: true,
2241
+ actionType: exports.TOOL_OPERATION_IDS.contentCreateDraft,
2242
+ buildSummary: (input) => buildCreateDraftConfirmationSummary(input)
2243
+ },
2244
+ idempotency: {
2245
+ required: true,
2246
+ buildKey: (input, context) => [
2247
+ exports.TOOL_OPERATION_IDS.contentCreateDraft,
2248
+ context.workspaceId,
2249
+ input.integrationId,
2250
+ input.idempotencyKey?.trim() || shortStableHash(input)
2251
+ ].join(":")
2252
+ },
2253
+ surfaces: {
2254
+ agent: {
2255
+ name: exports.TOOL_WIRE_NAMES.contentCreateDraft.agent,
2256
+ description: "Creates a REAL saved draft in Maeve. Only call this when the user explicitly asks to save or create a draft. This always requires explicit user confirmation before executing.",
2257
+ access: "write",
2258
+ gated: false,
2259
+ safeInputSummary: (input) => [
2260
+ `integrationId=${input.integrationId}`,
2261
+ `media=${input.contentMedia?.length ?? 0}`,
2262
+ `title=${hasCreateDraftTitle(input) ? "present" : "absent"}`,
2263
+ `idempotencyKey=${input.idempotencyKey ? "present" : "absent"}`
2264
+ ].join(" ")
2265
+ },
2266
+ mcp: {
2267
+ name: exports.TOOL_WIRE_NAMES.contentCreateDraft.mcp,
2268
+ title: "Create Draft Content",
2269
+ description: "Create Maeve content as a draft only. Does not schedule or publish; platform settings require prior capability inspection.",
2270
+ scope: "mcp:write",
2271
+ toolsets: ["content_drafting", "content_workflow", "content_workflow_all"],
2272
+ annotations: {
2273
+ readOnlyHint: false,
2274
+ destructiveHint: false,
2275
+ idempotentHint: true,
2276
+ openWorldHint: false
2277
+ }
2278
+ }
2279
+ }
2280
+ };
2281
+ var updateDraftContentInputShape = {
2282
+ contentId: z9.string().uuid().describe("Draft or scheduled content ID to edit."),
2283
+ internalTitle: z9.string().max(500).nullable().optional().describe("Internal planning title. Never published. Pass null to clear."),
2284
+ publishTitle: z9.string().max(500).nullable().optional().describe("Provider-facing title for platforms that support or require one. Pass null to clear."),
2285
+ captions: createDraftCaptionsObjectSchema.optional().describe("Canonical caption and per-platform caption overrides: { canonical, overrides: {} }."),
2286
+ contentMedia: createDraftContentMediaSchema.optional().describe("Canonical media relationship input with per-content crops, tags, ordering, and cover metadata."),
2287
+ poll: createDraftLinkedinPollSchema.nullable().optional().describe("LinkedIn poll content. Required when postType is poll."),
2288
+ settings: createDraftContentSettingsSchema.optional().describe("Strict platform-specific provider settings. Inspect get_integration_capabilities first."),
2289
+ postType: z9.enum(PUBLIC_CONTENT_POST_TYPE_VALUES).optional().describe("Platform post type."),
2290
+ firstComment: z9.string().optional().describe("First comment text."),
2291
+ shareToFeed: z9.boolean().optional().describe("Feed-sharing setting."),
2292
+ threadMessages: z9.array(z9.object({
2293
+ captions: createDraftCaptionsObjectSchema,
2294
+ contentMedia: createDraftContentMediaSchema.optional()
2295
+ })).max(20).optional().describe("Thread/reply draft messages with canonical captions and media relationships.")
2296
+ };
2297
+ exports.updateDraftContentInputSchema = z9.object(updateDraftContentInputShape).strict();
2298
+ exports.updateDraftContentMcpInputSchema = z9.object({
2299
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
2300
+ ...updateDraftContentInputShape
2301
+ }).strict();
2302
+ exports.updateDraftContentOutputSchema = z9.object({
2303
+ content: z9.object({
2304
+ id: z9.string(),
2305
+ status: z9.string(),
2306
+ groupId: z9.string().optional(),
2307
+ contentIds: z9.array(z9.string()).optional()
2308
+ }).strict(),
2309
+ nextStep: z9.object({
2310
+ action: z9.literal("review_content"),
2311
+ tool: z9.literal("get_content")
2312
+ }).strict()
2313
+ }).strict();
2314
+ exports.CONTENT_UPDATE_DRAFT_CONTRACT = {
2315
+ canonicalName: exports.TOOL_OPERATION_IDS.contentUpdateDraft,
2316
+ wireNames: exports.TOOL_WIRE_NAMES.contentUpdateDraft,
2317
+ description: "Edit an existing draft or scheduled content item: caption, per-platform caption overrides, media, provider settings, post type, first comment, feed sharing, titles, and thread messages. Omitted fields remain unchanged. Use update_content_metadata for planning fields, update_content_notes for notes, and schedule_content for scheduling.",
2318
+ inputSchema: exports.updateDraftContentInputSchema,
2319
+ wireInputSchemas: {
2320
+ mcp: exports.updateDraftContentMcpInputSchema
2321
+ },
2322
+ outputSchema: exports.updateDraftContentOutputSchema,
2323
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.contentDraftUpdate],
2324
+ confirmation: {
2325
+ required: true,
2326
+ actionType: exports.TOOL_OPERATION_IDS.contentUpdateDraft,
2327
+ buildSummary: (input) => buildUpdateDraftConfirmationSummary(input)
2328
+ },
2329
+ idempotency: {
2330
+ required: true,
2331
+ buildKey: (input, context) => [exports.TOOL_OPERATION_IDS.contentUpdateDraft, context.workspaceId, input.contentId, shortStableHash(input)].join(":")
2332
+ },
2333
+ surfaces: {
2334
+ agent: {
2335
+ name: exports.TOOL_WIRE_NAMES.contentUpdateDraft.agent,
2336
+ description: "Updates a REAL saved draft or scheduled content item in Maeve. Only call this when the user explicitly asks to edit saved content. This always requires explicit user confirmation before executing.",
2337
+ access: "write",
2338
+ gated: false,
2339
+ safeInputSummary: (input) => [
2340
+ `contentId=${input.contentId}`,
2341
+ `media=${input.contentMedia?.length ?? 0}`,
2342
+ `title=${hasUpdateDraftTitle(input) ? "present" : "absent"}`,
2343
+ `fields=${countUpdateDraftFields(input)}`
2344
+ ].join(" ")
2345
+ },
2346
+ mcp: {
2347
+ name: exports.TOOL_WIRE_NAMES.contentUpdateDraft.mcp,
2348
+ title: "Update Content",
2349
+ description: "Edit an existing draft or scheduled content item: caption, per-platform caption overrides, media, provider settings, post type, first comment, feed sharing, titles, and thread messages. Omitted fields remain unchanged. Use update_content_metadata for planning fields, update_content_notes for notes, and schedule_content for scheduling.",
2350
+ scope: "mcp:write",
2351
+ toolsets: ["content_drafting", "content_workflow", "content_workflow_all"],
2352
+ annotations: {
2353
+ readOnlyHint: false,
2354
+ destructiveHint: false,
2355
+ idempotentHint: true,
2356
+ openWorldHint: false
2357
+ }
2358
+ }
2359
+ }
2360
+ };
2361
+ var contentMetadataUuidArraySchema = z9.array(z9.string().uuid());
2362
+ var updateContentMetadataInputShape = {
2363
+ contentId: z9.string().uuid().describe("Content ID whose planning metadata should be updated."),
2364
+ labelIds: contentMetadataUuidArraySchema.optional().describe("Replacement workspace content label IDs. Empty array clears."),
2365
+ pillarIds: contentMetadataUuidArraySchema.optional().describe("Replacement content pillar IDs. Empty array clears."),
2366
+ formatIds: contentMetadataUuidArraySchema.optional().describe("Replacement content format IDs. Empty array clears."),
2367
+ assigneeIds: contentMetadataUuidArraySchema.optional().describe("Replacement assignee user IDs. Empty array clears."),
2368
+ priority: z9.enum(WORKBENCH_PRIORITY_VALUES).nullable().optional().describe("Optional workbench priority. Pass null to clear."),
2369
+ campaignId: z9.string().uuid().nullable().optional().describe("Optional campaign ID. Pass null to clear campaign and phase."),
2370
+ campaignPhaseId: z9.string().uuid().nullable().optional().describe("Optional campaign phase ID. Pass null to clear phase while leaving campaign unchanged.")
2371
+ };
2372
+ exports.updateContentMetadataInputSchema = z9.object(updateContentMetadataInputShape).strict();
2373
+ exports.updateContentMetadataMcpInputSchema = z9.object({
2374
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
2375
+ ...updateContentMetadataInputShape
2376
+ }).strict();
2377
+ var updateContentNotesInputShape = {
2378
+ contentId: z9.string().uuid().describe("Content ID whose notes should be updated."),
2379
+ notes: z9.string().max(1e5).describe("Rich-text notes content (HTML). Replaces the entire notes body.")
2380
+ };
2381
+ exports.updateContentNotesInputSchema = z9.object(updateContentNotesInputShape).strict();
2382
+ exports.updateContentNotesMcpInputSchema = z9.object({
2383
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
2384
+ ...updateContentNotesInputShape
2385
+ });
2386
+ var publicContentLabelOutputSchema = z9.object({
2387
+ id: z9.string(),
2388
+ name: z9.string(),
2389
+ color: z9.string().nullable(),
2390
+ groupId: z9.string().nullable(),
2391
+ archivedAt: z9.string().nullable(),
2392
+ mergedIntoLabelId: z9.string().nullable(),
2393
+ mergedAt: z9.string().nullable(),
2394
+ mergedByUserId: z9.string().nullable()
2395
+ }).strict();
2396
+ var publicContentPillarOutputSchema = z9.object({
2397
+ id: z9.string(),
2398
+ name: z9.string(),
2399
+ color: z9.string().nullable(),
2400
+ description: z9.string().nullable(),
2401
+ sortOrder: z9.number(),
2402
+ archivedAt: z9.string().nullable()
2403
+ }).strict();
2404
+ var publicContentFormatOutputSchema = z9.object({
2405
+ id: z9.string(),
2406
+ name: z9.string(),
2407
+ color: z9.string().nullable(),
2408
+ description: z9.string().nullable(),
2409
+ sortOrder: z9.number(),
2410
+ isSeeded: z9.boolean(),
2411
+ archivedAt: z9.string().nullable()
2412
+ }).strict();
2413
+ exports.updateContentMetadataOutputSchema = z9.object({
2414
+ content: z9.object({
2415
+ id: z9.string(),
2416
+ workspaceId: z9.string(),
2417
+ status: z9.string(),
2418
+ workflowStatus: z9.string().nullable(),
2419
+ labelIds: z9.array(z9.string()),
2420
+ labels: z9.array(publicContentLabelOutputSchema),
2421
+ pillarIds: z9.array(z9.string()),
2422
+ pillars: z9.array(publicContentPillarOutputSchema),
2423
+ formatIds: z9.array(z9.string()),
2424
+ formats: z9.array(publicContentFormatOutputSchema),
2425
+ assigneeIds: z9.array(z9.string()),
2426
+ assignees: z9.array(boundedStringRecordSchema),
2427
+ priority: z9.enum(WORKBENCH_PRIORITY_VALUES).nullable(),
2428
+ campaignId: z9.string().nullable(),
2429
+ campaignPhaseId: z9.string().nullable(),
2430
+ updatedAt: z9.string().nullable()
2431
+ }).strict(),
2432
+ nextStep: z9.object({
2433
+ action: z9.literal("review_content"),
2434
+ tool: z9.literal("get_content")
2435
+ }).strict()
2436
+ }).strict();
2437
+ exports.updateContentNotesOutputSchema = z9.object({
2438
+ content: z9.object({
2439
+ id: z9.string(),
2440
+ workspaceId: z9.string(),
2441
+ status: z9.literal("updated")
2442
+ }).strict()
2443
+ }).strict();
2444
+ exports.CONTENT_UPDATE_METADATA_CONTRACT = {
2445
+ canonicalName: exports.TOOL_OPERATION_IDS.contentUpdateMetadata,
2446
+ wireNames: exports.TOOL_WIRE_NAMES.contentUpdateMetadata,
2447
+ description: "Update planning metadata on one existing draft or scheduled content item. Omitted fields remain unchanged; provided arrays replace existing assignments and empty arrays clear.",
2448
+ inputSchema: exports.updateContentMetadataInputSchema,
2449
+ wireInputSchemas: {
2450
+ mcp: exports.updateContentMetadataMcpInputSchema
2451
+ },
2452
+ outputSchema: exports.updateContentMetadataOutputSchema,
2453
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.contentDraftUpdate],
2454
+ confirmation: {
2455
+ required: true,
2456
+ actionType: exports.TOOL_OPERATION_IDS.contentUpdateMetadata,
2457
+ buildSummary: (input) => buildUpdateMetadataConfirmationSummary(input)
2458
+ },
2459
+ idempotency: {
2460
+ required: true,
2461
+ buildKey: (input, context) => [exports.TOOL_OPERATION_IDS.contentUpdateMetadata, context.workspaceId, input.contentId, shortStableHash(input)].join(":")
2462
+ },
2463
+ surfaces: {
2464
+ agent: {
2465
+ name: exports.TOOL_WIRE_NAMES.contentUpdateMetadata.agent,
2466
+ description: "Updates REAL saved content planning metadata in Maeve: labels, pillars, formats, assignees, priority, campaign, and campaign phase. This always requires explicit user confirmation before executing.",
2467
+ access: "write",
2468
+ gated: false,
2469
+ safeInputSummary: (input) => [
2470
+ `contentId=${input.contentId}`,
2471
+ `fields=${countUpdateMetadataFields(input)}`,
2472
+ `labels=${input.labelIds?.length ?? "unchanged"}`,
2473
+ `assignees=${input.assigneeIds?.length ?? "unchanged"}`
2474
+ ].join(" ")
2475
+ },
2476
+ mcp: {
2477
+ name: exports.TOOL_WIRE_NAMES.contentUpdateMetadata.mcp,
2478
+ title: "Update Content Metadata",
2479
+ description: "Update planning metadata on one existing draft or scheduled content item. Omitted fields remain unchanged; provided arrays replace existing assignments and empty arrays clear.",
2480
+ scope: "mcp:write",
2481
+ toolsets: ["content_drafting", "content_workflow", "content_workflow_all"],
2482
+ annotations: {
2483
+ readOnlyHint: false,
2484
+ destructiveHint: false,
2485
+ idempotentHint: true,
2486
+ openWorldHint: false
2487
+ }
2488
+ }
2489
+ }
2490
+ };
2491
+ exports.CONTENT_UPDATE_NOTES_CONTRACT = {
2492
+ canonicalName: exports.TOOL_OPERATION_IDS.contentUpdateNotes,
2493
+ wireNames: exports.TOOL_WIRE_NAMES.contentUpdateNotes,
2494
+ description: "Replace the rich-text notes attached to an Maeve content item. Notes are internal and never published. Pass an empty string to clear.",
2495
+ inputSchema: exports.updateContentNotesInputSchema,
2496
+ wireInputSchemas: {
2497
+ mcp: exports.updateContentNotesMcpInputSchema
2498
+ },
2499
+ outputSchema: exports.updateContentNotesOutputSchema,
2500
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.contentDraftUpdate],
2501
+ confirmation: {
2502
+ required: true,
2503
+ actionType: exports.TOOL_OPERATION_IDS.contentUpdateNotes,
2504
+ buildSummary: (input) => buildUpdateNotesConfirmationSummary(input)
2505
+ },
2506
+ idempotency: {
2507
+ required: true,
2508
+ buildKey: (input, context) => [exports.TOOL_OPERATION_IDS.contentUpdateNotes, context.workspaceId, input.contentId, shortStableHash(input)].join(":")
2509
+ },
2510
+ surfaces: {
2511
+ agent: {
2512
+ name: exports.TOOL_WIRE_NAMES.contentUpdateNotes.agent,
2513
+ description: "Updates REAL internal notes on saved Maeve content. Notes are never published. This always requires explicit user confirmation before executing.",
2514
+ access: "write",
2515
+ gated: false,
2516
+ safeInputSummary: (input) => `contentId=${input.contentId} notesLength=${input.notes.length}`
2517
+ },
2518
+ mcp: {
2519
+ name: exports.TOOL_WIRE_NAMES.contentUpdateNotes.mcp,
2520
+ title: "Update Content Notes",
2521
+ description: "Replace the rich-text notes attached to an Maeve content item. Notes are internal and never published. Pass an empty string to clear.",
2522
+ scope: "mcp:write",
2523
+ toolsets: ["content_drafting", "content_workflow", "content_workflow_all"],
2524
+ annotations: {
2525
+ readOnlyHint: false,
2526
+ destructiveHint: false,
2527
+ idempotentHint: true,
2528
+ openWorldHint: false
2529
+ }
2530
+ }
2531
+ }
2532
+ };
2533
+ var contentScheduleInputShape = {
2534
+ contentId: z9.string().uuid().describe("Content ID to schedule or reschedule."),
2535
+ scheduledAt: z9.string().describe("ISO-8601 scheduled time. Include a timezone, or omit it to use the workspace timezone, for example 2026-05-01T09:00:00.")
2536
+ };
2537
+ exports.contentScheduleInputSchema = z9.object(contentScheduleInputShape).strict();
2538
+ exports.contentScheduleMcpInputSchema = z9.object({
2539
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
2540
+ ...contentScheduleInputShape
2541
+ }).strict();
2542
+ var publicContentMutationOutputSchema = z9.object({
2543
+ id: z9.string(),
2544
+ status: z9.string(),
2545
+ groupId: z9.string().optional(),
2546
+ contentIds: z9.array(z9.string()).optional()
2547
+ }).strict();
2548
+ var lifecycleConfirmationModeSchema = z9.enum(["explicit_confirmation", "dangerous_auto_confirm"]);
2549
+ exports.contentScheduleOutputSchema = z9.object({
2550
+ content: publicContentMutationOutputSchema.extend({
2551
+ workspaceId: z9.string(),
2552
+ scheduledAt: z9.string()
2553
+ }).strict(),
2554
+ nextReviewState: z9.object({
2555
+ status: z9.string(),
2556
+ action: z9.literal("scheduled")
2557
+ }).strict()
2558
+ }).strict();
2559
+ var publishNowInputShape = {
2560
+ contentId: z9.string().uuid().describe("Draft or scheduled content ID to publish now."),
2561
+ confirmationText: z9.string().optional().describe("Exact confirmation text: publish_now:<contentId>."),
2562
+ dangerouslyAutoConfirm: z9.boolean().optional().describe("Only honored when server-side dangerous auto-confirm policy allows publish_now.")
2563
+ };
2564
+ exports.publishNowInputSchema = z9.object(publishNowInputShape).strict();
2565
+ exports.publishNowMcpInputSchema = z9.object({
2566
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
2567
+ ...publishNowInputShape
2568
+ }).strict();
2569
+ exports.publishNowOutputSchema = z9.object({
2570
+ content: publicContentMutationOutputSchema,
2571
+ confirmationMode: lifecycleConfirmationModeSchema,
2572
+ nextReviewState: z9.object({
2573
+ status: z9.string(),
2574
+ action: z9.literal("queued_for_immediate_publish")
2575
+ }).strict()
2576
+ }).strict();
2577
+ var archiveContentInputShape = {
2578
+ contentId: z9.string().uuid().describe("Published content ID to archive."),
2579
+ confirmationText: z9.string().optional().describe("Exact confirmation text: archive_content:<contentId>."),
2580
+ dangerouslyAutoConfirm: z9.boolean().optional().describe("Only honored when server-side dangerous auto-confirm policy allows archive_content.")
2581
+ };
2582
+ exports.archiveContentInputSchema = z9.object(archiveContentInputShape).strict();
2583
+ exports.archiveContentMcpInputSchema = z9.object({
2584
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
2585
+ ...archiveContentInputShape
2586
+ }).strict();
2587
+ var archiveContentMutationOutputSchema = z9.object({
2588
+ id: z9.string(),
2589
+ archivedAt: z9.string().nullable()
2590
+ }).strict();
2591
+ exports.archiveContentOutputSchema = z9.object({
2592
+ content: archiveContentMutationOutputSchema,
2593
+ confirmationMode: lifecycleConfirmationModeSchema,
2594
+ nextReviewState: z9.object({
2595
+ status: z9.literal("archived"),
2596
+ action: z9.literal("inspect_content")
2597
+ }).strict()
2598
+ }).strict();
2599
+ var restoreContentInputShape = {
2600
+ contentId: z9.string().uuid().describe("Archived content ID to restore."),
2601
+ confirmationText: z9.string().optional().describe("Exact confirmation text: restore_content:<contentId>."),
2602
+ dangerouslyAutoConfirm: z9.boolean().optional().describe("Only honored when server-side dangerous auto-confirm policy allows restore_content.")
2603
+ };
2604
+ exports.restoreContentInputSchema = z9.object(restoreContentInputShape).strict();
2605
+ exports.restoreContentMcpInputSchema = z9.object({
2606
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
2607
+ ...restoreContentInputShape
2608
+ }).strict();
2609
+ exports.restoreContentOutputSchema = z9.object({
2610
+ content: archiveContentMutationOutputSchema,
2611
+ confirmationMode: lifecycleConfirmationModeSchema,
2612
+ nextReviewState: z9.object({
2613
+ status: z9.literal("restored"),
2614
+ action: z9.literal("inspect_content")
2615
+ }).strict()
2616
+ }).strict();
2617
+ var retryContentInputShape = {
2618
+ contentId: z9.string().uuid().describe("Failed content ID to retry."),
2619
+ confirmationText: z9.string().optional().describe("Exact confirmation text: retry_content:<contentId>."),
2620
+ dangerouslyAutoConfirm: z9.boolean().optional().describe("Only honored when server-side dangerous auto-confirm policy allows retry_content.")
2621
+ };
2622
+ exports.retryContentInputSchema = z9.object(retryContentInputShape).strict();
2623
+ exports.retryContentMcpInputSchema = z9.object({
2624
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
2625
+ ...retryContentInputShape
2626
+ }).strict();
2627
+ exports.retryContentOutputSchema = z9.object({
2628
+ content: publicContentMutationOutputSchema,
2629
+ confirmationMode: lifecycleConfirmationModeSchema,
2630
+ nextReviewState: z9.object({
2631
+ status: z9.string(),
2632
+ action: z9.literal("queued_for_retry")
2633
+ }).strict()
2634
+ }).strict();
2635
+ var deleteContentInputShape = {
2636
+ contentId: z9.string().uuid().describe("Content ID to delete."),
2637
+ confirmationText: z9.string().optional().describe("Exact confirmation text: delete_content:<contentId>."),
2638
+ dangerouslyAutoConfirm: z9.boolean().optional().describe("Only honored when server-side dangerous auto-confirm policy allows delete_content.")
2639
+ };
2640
+ exports.deleteContentInputSchema = z9.object(deleteContentInputShape).strict();
2641
+ exports.deleteContentMcpInputSchema = z9.object({
2642
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
2643
+ ...deleteContentInputShape
2644
+ }).strict();
2645
+ var deleteContentModeSchema = z9.enum(["hard_deleted", "platform_deleted"]);
2646
+ exports.deleteContentOutputSchema = z9.object({
2647
+ content: z9.object({
2648
+ mode: deleteContentModeSchema,
2649
+ postId: z9.string()
2650
+ }).strict(),
2651
+ confirmationMode: lifecycleConfirmationModeSchema,
2652
+ nextReviewState: z9.object({
2653
+ status: deleteContentModeSchema,
2654
+ action: z9.literal("content_deleted")
2655
+ }).strict()
2656
+ }).strict();
2657
+ exports.CONTENT_SCHEDULE_CONTRACT = {
2658
+ canonicalName: exports.TOOL_OPERATION_IDS.contentSchedule,
2659
+ wireNames: exports.TOOL_WIRE_NAMES.contentSchedule,
2660
+ description: "Schedule or reschedule an existing draft or scheduled Maeve content item. This schedules real publishing on the connected external account and creates the publishing queue job.",
2661
+ inputSchema: exports.contentScheduleInputSchema,
2662
+ wireInputSchemas: {
2663
+ mcp: exports.contentScheduleMcpInputSchema
2664
+ },
2665
+ outputSchema: exports.contentScheduleOutputSchema,
2666
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.contentSchedule],
2667
+ confirmation: {
2668
+ required: true,
2669
+ actionType: exports.TOOL_OPERATION_IDS.contentSchedule,
2670
+ buildSummary: (input) => buildScheduleConfirmationSummary(input)
2671
+ },
2672
+ idempotency: {
2673
+ required: true,
2674
+ buildKey: (input, context) => [exports.TOOL_OPERATION_IDS.contentSchedule, context.workspaceId, input.contentId, shortStableHash(input)].join(":")
2675
+ },
2676
+ surfaces: {
2677
+ agent: {
2678
+ name: exports.TOOL_WIRE_NAMES.contentSchedule.agent,
2679
+ description: "Schedules REAL saved content for publishing on the connected external account and creates the publishing queue job. This always requires explicit user confirmation before executing.",
2680
+ access: "write",
2681
+ gated: false,
2682
+ safeInputSummary: (input) => `contentId=${input.contentId} scheduledAt=${input.scheduledAt}`
2683
+ },
2684
+ mcp: {
2685
+ name: exports.TOOL_WIRE_NAMES.contentSchedule.mcp,
2686
+ title: "Schedule Content",
2687
+ description: "Schedule or reschedule an existing draft/scheduled Maeve content item. Timezone-qualified ISO-8601 values are used as provided; local ISO-8601 values without a timezone are interpreted in the workspace timezone. If reviewLifecycle is present or a review guard blocks scheduling, use blockers and nextAction instead of content.status alone.",
2688
+ scope: "mcp:write",
2689
+ toolsets: ["content_scheduling", "content_workflow", "content_workflow_all"],
2690
+ annotations: {
2691
+ readOnlyHint: false,
2692
+ destructiveHint: false,
2693
+ idempotentHint: false,
2694
+ openWorldHint: false
2695
+ }
2696
+ }
2697
+ }
2698
+ };
2699
+ exports.CONTENT_PUBLISH_NOW_CONTRACT = {
2700
+ canonicalName: exports.TOOL_OPERATION_IDS.contentPublishNow,
2701
+ wireNames: exports.TOOL_WIRE_NAMES.contentPublishNow,
2702
+ description: "Immediately queue a draft or scheduled Maeve content item for publishing on the connected external account.",
2703
+ inputSchema: exports.publishNowInputSchema,
2704
+ wireInputSchemas: {
2705
+ mcp: exports.publishNowMcpInputSchema
2706
+ },
2707
+ outputSchema: exports.publishNowOutputSchema,
2708
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.contentPublishNow],
2709
+ confirmation: {
2710
+ required: true,
2711
+ actionType: exports.TOOL_OPERATION_IDS.contentPublishNow,
2712
+ buildSummary: (input) => buildPublishNowConfirmationSummary(input)
2713
+ },
2714
+ idempotency: {
2715
+ required: true,
2716
+ buildKey: (input, context) => [exports.TOOL_OPERATION_IDS.contentPublishNow, context.workspaceId, input.contentId, shortStableHash(input)].join(":")
2717
+ },
2718
+ surfaces: {
2719
+ agent: {
2720
+ name: exports.TOOL_WIRE_NAMES.contentPublishNow.agent,
2721
+ description: "Publishes REAL saved content immediately on the connected external account. This always requires explicit user confirmation before executing.",
2722
+ access: "write",
2723
+ gated: false,
2724
+ safeInputSummary: (input) => `contentId=${input.contentId}`
2725
+ },
2726
+ mcp: {
2727
+ name: exports.TOOL_WIRE_NAMES.contentPublishNow.mcp,
2728
+ title: "Publish Now",
2729
+ description: "Immediately queue a draft or scheduled Maeve content item for publishing. High-risk: requires exact confirmation text or server-enabled dangerous auto-confirm. If reviewLifecycle is present or a publish guard blocks execution, use blockers and nextAction instead of content.status alone.",
2730
+ scope: "mcp:dangerous",
2731
+ toolsets: ["content_dangerous", "content_workflow_all"],
2732
+ annotations: {
2733
+ readOnlyHint: false,
2734
+ destructiveHint: false,
2735
+ idempotentHint: false,
2736
+ openWorldHint: true
2737
+ }
2738
+ }
2739
+ }
2740
+ };
2741
+ exports.CONTENT_ARCHIVE_CONTRACT = {
2742
+ canonicalName: exports.TOOL_OPERATION_IDS.contentArchive,
2743
+ wireNames: exports.TOOL_WIRE_NAMES.contentArchive,
2744
+ description: "Archive a published Maeve content item. High-risk: requires exact confirmation text or server-enabled dangerous auto-confirm.",
2745
+ inputSchema: exports.archiveContentInputSchema,
2746
+ wireInputSchemas: {
2747
+ mcp: exports.archiveContentMcpInputSchema
2748
+ },
2749
+ outputSchema: exports.archiveContentOutputSchema,
2750
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.contentDraftArchive],
2751
+ confirmation: {
2752
+ required: true,
2753
+ actionType: exports.TOOL_OPERATION_IDS.contentArchive,
2754
+ buildSummary: (input) => buildArchiveConfirmationSummary(input)
2755
+ },
2756
+ idempotency: {
2757
+ required: true,
2758
+ buildKey: (input, context) => [exports.TOOL_OPERATION_IDS.contentArchive, context.workspaceId, input.contentId, shortStableHash(input)].join(":")
2759
+ },
2760
+ surfaces: {
2761
+ agent: {
2762
+ name: exports.TOOL_WIRE_NAMES.contentArchive.agent,
2763
+ description: "Archives REAL published saved content in Maeve. This always requires explicit user confirmation before executing.",
2764
+ access: "write",
2765
+ gated: false,
2766
+ safeInputSummary: (input) => `contentId=${input.contentId}`
2767
+ },
2768
+ mcp: {
2769
+ name: exports.TOOL_WIRE_NAMES.contentArchive.mcp,
2770
+ title: "Archive Content",
2771
+ description: "Archive a published Maeve content item. High-risk: requires exact confirmation text or server-enabled dangerous auto-confirm.",
2772
+ scope: "mcp:dangerous",
2773
+ toolsets: ["content_dangerous", "content_workflow_all"],
2774
+ annotations: {
2775
+ readOnlyHint: false,
2776
+ destructiveHint: true,
2777
+ idempotentHint: true,
2778
+ openWorldHint: false
2779
+ }
2780
+ }
2781
+ }
2782
+ };
2783
+ exports.CONTENT_RESTORE_CONTRACT = {
2784
+ canonicalName: exports.TOOL_OPERATION_IDS.contentRestore,
2785
+ wireNames: exports.TOOL_WIRE_NAMES.contentRestore,
2786
+ description: "Restore an archived Maeve content item. High-risk: requires exact confirmation text or server-enabled dangerous auto-confirm.",
2787
+ inputSchema: exports.restoreContentInputSchema,
2788
+ wireInputSchemas: {
2789
+ mcp: exports.restoreContentMcpInputSchema
2790
+ },
2791
+ outputSchema: exports.restoreContentOutputSchema,
2792
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.contentDraftRestore],
2793
+ confirmation: {
2794
+ required: true,
2795
+ actionType: exports.TOOL_OPERATION_IDS.contentRestore,
2796
+ buildSummary: (input) => buildRestoreConfirmationSummary(input)
2797
+ },
2798
+ idempotency: {
2799
+ required: true,
2800
+ buildKey: (input, context) => [exports.TOOL_OPERATION_IDS.contentRestore, context.workspaceId, input.contentId, shortStableHash(input)].join(":")
2801
+ },
2802
+ surfaces: {
2803
+ agent: {
2804
+ name: exports.TOOL_WIRE_NAMES.contentRestore.agent,
2805
+ description: "Restores REAL archived saved content in Maeve. This always requires explicit user confirmation before executing.",
2806
+ access: "write",
2807
+ gated: false,
2808
+ safeInputSummary: (input) => `contentId=${input.contentId}`
2809
+ },
2810
+ mcp: {
2811
+ name: exports.TOOL_WIRE_NAMES.contentRestore.mcp,
2812
+ title: "Restore Content",
2813
+ description: "Restore an archived Maeve content item. High-risk: requires exact confirmation text or server-enabled dangerous auto-confirm.",
2814
+ scope: "mcp:dangerous",
2815
+ toolsets: ["content_dangerous", "content_workflow_all"],
2816
+ annotations: {
2817
+ readOnlyHint: false,
2818
+ destructiveHint: false,
2819
+ idempotentHint: true,
2820
+ openWorldHint: false
2821
+ }
2822
+ }
2823
+ }
2824
+ };
2825
+ exports.CONTENT_RETRY_CONTRACT = {
2826
+ canonicalName: exports.TOOL_OPERATION_IDS.contentRetry,
2827
+ wireNames: exports.TOOL_WIRE_NAMES.contentRetry,
2828
+ description: "Retry a failed Maeve content item using the existing content retry rules. High-risk: requires exact confirmation text or server-enabled dangerous auto-confirm.",
2829
+ inputSchema: exports.retryContentInputSchema,
2830
+ wireInputSchemas: {
2831
+ mcp: exports.retryContentMcpInputSchema
2832
+ },
2833
+ outputSchema: exports.retryContentOutputSchema,
2834
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.contentRetryPublish],
2835
+ confirmation: {
2836
+ required: true,
2837
+ actionType: exports.TOOL_OPERATION_IDS.contentRetry,
2838
+ buildSummary: (input) => buildRetryConfirmationSummary(input)
2839
+ },
2840
+ idempotency: {
2841
+ required: true,
2842
+ buildKey: (input, context) => [exports.TOOL_OPERATION_IDS.contentRetry, context.workspaceId, input.contentId, shortStableHash(input)].join(":")
2843
+ },
2844
+ surfaces: {
2845
+ agent: {
2846
+ name: exports.TOOL_WIRE_NAMES.contentRetry.agent,
2847
+ description: "Retries REAL failed saved content publishing on the connected external account. This always requires explicit user confirmation before executing.",
2848
+ access: "write",
2849
+ gated: false,
2850
+ safeInputSummary: (input) => `contentId=${input.contentId}`
2851
+ },
2852
+ mcp: {
2853
+ name: exports.TOOL_WIRE_NAMES.contentRetry.mcp,
2854
+ title: "Retry Content",
2855
+ description: "Retry a failed Maeve content item using the existing content retry rules. High-risk: requires exact confirmation text or server-enabled dangerous auto-confirm.",
2856
+ scope: "mcp:dangerous",
2857
+ toolsets: ["content_dangerous", "content_workflow_all"],
2858
+ annotations: {
2859
+ readOnlyHint: false,
2860
+ destructiveHint: false,
2861
+ idempotentHint: false,
2862
+ openWorldHint: true
2863
+ }
2864
+ }
2865
+ }
2866
+ };
2867
+ exports.CONTENT_DELETE_CONTRACT = {
2868
+ canonicalName: exports.TOOL_OPERATION_IDS.contentDelete,
2869
+ wireNames: exports.TOOL_WIRE_NAMES.contentDelete,
2870
+ description: "Delete an Maeve content item using the existing content deletion rules. High-risk: requires exact confirmation text or server-enabled dangerous auto-confirm.",
2871
+ inputSchema: exports.deleteContentInputSchema,
2872
+ wireInputSchemas: {
2873
+ mcp: exports.deleteContentMcpInputSchema
2874
+ },
2875
+ outputSchema: exports.deleteContentOutputSchema,
2876
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.contentDraftDelete],
2877
+ confirmation: {
2878
+ required: true,
2879
+ actionType: exports.TOOL_OPERATION_IDS.contentDelete,
2880
+ buildSummary: (input) => buildDeleteConfirmationSummary(input)
2881
+ },
2882
+ idempotency: {
2883
+ required: true,
2884
+ buildKey: (input, context) => [exports.TOOL_OPERATION_IDS.contentDelete, context.workspaceId, input.contentId, shortStableHash(input)].join(":")
2885
+ },
2886
+ surfaces: {
2887
+ agent: {
2888
+ name: exports.TOOL_WIRE_NAMES.contentDelete.agent,
2889
+ description: "Permanently deletes REAL saved content in Maeve using the existing content deletion rules. This always requires explicit user confirmation before executing.",
2890
+ access: "write",
2891
+ gated: false,
2892
+ safeInputSummary: (input) => `contentId=${input.contentId}`
2893
+ },
2894
+ mcp: {
2895
+ name: exports.TOOL_WIRE_NAMES.contentDelete.mcp,
2896
+ title: "Delete Content",
2897
+ description: "Delete an Maeve content item using the existing content deletion rules. High-risk: requires exact confirmation text or server-enabled dangerous auto-confirm.",
2898
+ scope: "mcp:dangerous",
2899
+ toolsets: ["content_dangerous", "content_workflow_all"],
2900
+ annotations: {
2901
+ readOnlyHint: false,
2902
+ destructiveHint: true,
2903
+ idempotentHint: false,
2904
+ openWorldHint: true
2905
+ }
2906
+ }
2907
+ }
2908
+ };
2909
+ function buildCreateDraftConfirmationSummary(input) {
2910
+ const title = truncateText(resolveCreateDraftTitle(input), 120);
2911
+ const captionPreview = title ? null : truncateText(input.captions?.canonical, 120);
2912
+ const target = `integration ${input.integrationId}`;
2913
+ if (title)
2914
+ return `Create a saved draft for ${target}: "${title}".`;
2915
+ if (captionPreview)
2916
+ return `Create a saved draft for ${target}: "${captionPreview}".`;
2917
+ return `Create a saved draft for ${target}.`;
2918
+ }
2919
+ function hasCreateDraftTitle(input) {
2920
+ return Boolean(resolveCreateDraftTitle(input));
2921
+ }
2922
+ function resolveCreateDraftTitle(input) {
2923
+ return input.internalTitle?.trim() || input.publishTitle?.trim() || null;
2924
+ }
2925
+ function buildUpdateDraftConfirmationSummary(input) {
2926
+ const title = truncateText(resolveUpdateDraftTitle(input), 120);
2927
+ if (title)
2928
+ return `Update saved content ${input.contentId}: "${title}".`;
2929
+ return `Update saved content ${input.contentId}.`;
2930
+ }
2931
+ function hasUpdateDraftTitle(input) {
2932
+ return Boolean(resolveUpdateDraftTitle(input));
2933
+ }
2934
+ function resolveUpdateDraftTitle(input) {
2935
+ return input.internalTitle?.trim() || input.publishTitle?.trim() || null;
2936
+ }
2937
+ function countUpdateDraftFields(input) {
2938
+ const record = input;
2939
+ return Object.keys(updateDraftContentInputShape).filter((field) => field !== "contentId" && Object.prototype.hasOwnProperty.call(record, field)).length;
2940
+ }
2941
+ function buildUpdateMetadataConfirmationSummary(input) {
2942
+ const fields = countUpdateMetadataFields(input);
2943
+ return `Update saved content ${input.contentId} metadata (${fields} ${fields === 1 ? "field" : "fields"}).`;
2944
+ }
2945
+ function countUpdateMetadataFields(input) {
2946
+ const record = input;
2947
+ return Object.keys(updateContentMetadataInputShape).filter((field) => field !== "contentId" && Object.prototype.hasOwnProperty.call(record, field)).length;
2948
+ }
2949
+ function buildUpdateNotesConfirmationSummary(input) {
2950
+ return `Update internal notes for saved content ${input.contentId}.`;
2951
+ }
2952
+ function buildScheduleConfirmationSummary(input) {
2953
+ return `Schedule real publishing for saved content ${input.contentId} on the connected external account at ${input.scheduledAt}.`;
2954
+ }
2955
+ function buildPublishNowConfirmationSummary(input) {
2956
+ return `Publish saved content ${input.contentId} immediately to the connected external account.`;
2957
+ }
2958
+ function buildArchiveConfirmationSummary(input) {
2959
+ return `Archive saved content ${input.contentId}.`;
2960
+ }
2961
+ function buildRestoreConfirmationSummary(input) {
2962
+ return `Restore saved content ${input.contentId}.`;
2963
+ }
2964
+ function buildRetryConfirmationSummary(input) {
2965
+ return `Retry saved content ${input.contentId} by re-attempting a real publish on the connected external account.`;
2966
+ }
2967
+ function buildDeleteConfirmationSummary(input) {
2968
+ return `Permanently delete saved content ${input.contentId}. This will delete the content item from Maeve and cannot be undone.`;
2969
+ }
2970
+ function shortStableHash(value) {
2971
+ const text = stableStringify(value);
2972
+ let hash = 2166136261;
2973
+ for (let index = 0; index < text.length; index += 1) {
2974
+ hash ^= text.charCodeAt(index);
2975
+ hash = Math.imul(hash, 16777619);
2976
+ }
2977
+ return `generated-${(hash >>> 0).toString(16).padStart(8, "0")}`;
2978
+ }
2979
+ function stableStringify(value) {
2980
+ if (value === void 0)
2981
+ return "null";
2982
+ if (value === null)
2983
+ return "null";
2984
+ if (typeof value !== "object")
2985
+ return JSON.stringify(value);
2986
+ if (Array.isArray(value))
2987
+ return `[${value.map(stableStringify).join(",")}]`;
2988
+ const record = value;
2989
+ return `{${Object.keys(record).filter((key) => record[key] !== void 0).sort().map((key) => `${JSON.stringify(key)}:${stableStringify(record[key])}`).join(",")}}`;
2990
+ }
2991
+ function truncateText(value, maxLength) {
2992
+ const trimmed = value?.trim();
2993
+ if (!trimmed)
2994
+ return null;
2995
+ return trimmed.length > maxLength ? `${trimmed.slice(0, maxLength - 3)}...` : trimmed;
2996
+ }
2997
+ exports.contentSetIntendedPublishTimeInputSchema = z9.object({
2998
+ contentId: z9.string().uuid().describe("Draft or pending approval content ID."),
2999
+ scheduledAt: timezoneQualifiedTimestampSchema
3000
+ }).strict();
3001
+ exports.contentSetIntendedPublishTimeMcpInputSchema = z9.object({
3002
+ workspaceId: z9.string().uuid().describe("Maeve workspace ID."),
3003
+ contentId: z9.string().uuid().describe("Draft or pending approval content ID."),
3004
+ scheduledAt: z9.string().describe("ISO-8601 intended publish time. Include a timezone, or omit it to use the workspace timezone, for example 2026-05-01T09:00:00.")
3005
+ }).strict();
3006
+ exports.contentSetIntendedPublishTimeOutputSchema = z9.object({
3007
+ ok: z9.literal(true),
3008
+ renderHint: z9.literal("intended_publish_time"),
3009
+ timezone: z9.string(),
3010
+ content: z9.object({
3011
+ contentId: z9.string(),
3012
+ status: z9.enum(["draft", "pending_approval"]),
3013
+ scheduledAt: z9.string(),
3014
+ title: z9.string().nullable()
3015
+ }).strict()
3016
+ }).strict();
3017
+ exports.CONTENT_SET_INTENDED_PUBLISH_TIME_CONTRACT = {
3018
+ canonicalName: exports.TOOL_OPERATION_IDS.contentSetIntendedPublishTime,
3019
+ wireNames: exports.TOOL_WIRE_NAMES.contentSetIntendedPublishTime,
3020
+ description: "Set the intended publish time for draft or pending approval content. This is a planning write only and does not schedule, publish, or create a queue job.",
3021
+ inputSchema: exports.contentSetIntendedPublishTimeInputSchema,
3022
+ wireInputSchemas: {
3023
+ mcp: exports.contentSetIntendedPublishTimeMcpInputSchema
3024
+ },
3025
+ outputSchema: exports.contentSetIntendedPublishTimeOutputSchema,
3026
+ requiredCapabilities: [exports.TOOL_CAPABILITIES.contentReviewSetIntendedPublishTime],
3027
+ confirmation: {
3028
+ required: false
3029
+ },
3030
+ idempotency: {
3031
+ required: true,
3032
+ buildKey: (input, context) => `${exports.TOOL_OPERATION_IDS.contentSetIntendedPublishTime}:${context.workspaceId}:${input.contentId}:${input.scheduledAt}`
3033
+ },
3034
+ surfaces: {
3035
+ agent: {
3036
+ name: exports.TOOL_WIRE_NAMES.contentSetIntendedPublishTime.agent,
3037
+ description: "Set the intended publish time for draft or pending approval content. This is a planning write only and does not schedule, publish, or create a queue job.",
3038
+ access: "write",
3039
+ gated: false,
3040
+ safeInputSummary: (input) => `contentId=${input.contentId} scheduledAt=${input.scheduledAt}`
3041
+ },
3042
+ mcp: {
3043
+ name: exports.TOOL_WIRE_NAMES.contentSetIntendedPublishTime.mcp,
3044
+ title: "Set Intended Publish Time",
3045
+ description: "Set the intended publish time for draft or pending approval content. Does not schedule, publish, or create a BullMQ job.",
3046
+ scope: "mcp:write",
3047
+ toolsets: ["content_scheduling", "content_workflow", "content_workflow_all"],
3048
+ annotations: {
3049
+ readOnlyHint: false,
3050
+ destructiveHint: false,
3051
+ idempotentHint: true,
3052
+ openWorldHint: false
3053
+ }
3054
+ }
3055
+ }
3056
+ };
3057
+ exports.TOOL_CONTRACTS = [
3058
+ exports.WORKSPACE_SUMMARY_CONTRACT,
3059
+ exports.MEMORY_LIST_CONTRACT,
3060
+ exports.MEMORY_REMEMBER_CONTRACT,
3061
+ exports.CONTENT_FIND_RECENT_CONTRACT,
3062
+ exports.CALENDAR_READ_RANGE_CONTRACT,
3063
+ exports.CALENDAR_SUGGEST_PUBLISH_TIMES_CONTRACT,
3064
+ exports.MEDIA_SEARCH_CONTRACT,
3065
+ exports.COMPOSER_PATCH_CAPTION_CONTRACT,
3066
+ exports.COMPOSER_PATCH_SCHEDULE_CONTRACT,
3067
+ exports.COMPOSER_PATCH_TAXONOMY_CONTRACT,
3068
+ exports.COMPOSER_PATCH_MEDIA_CONTRACT,
3069
+ exports.CONTENT_LIST_CONTRACT,
3070
+ exports.CONTENT_GET_CONTRACT,
3071
+ exports.CONTENT_GET_COUNTS_CONTRACT,
3072
+ exports.INTEGRATIONS_LIST_CONTRACT,
3073
+ exports.INTEGRATIONS_GET_CAPABILITIES_CONTRACT,
3074
+ exports.INTEGRATIONS_GET_OPTIONS_CONTRACT,
3075
+ exports.TAXONOMY_LIST_CONTRACT,
3076
+ exports.CAMPAIGNS_LIST_CONTRACT,
3077
+ exports.HASHTAG_GROUPS_LIST_CONTRACT,
3078
+ exports.CONTENT_CREATE_DRAFT_CONTRACT,
3079
+ exports.CONTENT_UPDATE_DRAFT_CONTRACT,
3080
+ exports.CONTENT_UPDATE_METADATA_CONTRACT,
3081
+ exports.CONTENT_UPDATE_NOTES_CONTRACT,
3082
+ exports.CONTENT_SCHEDULE_CONTRACT,
3083
+ exports.CONTENT_PUBLISH_NOW_CONTRACT,
3084
+ exports.CONTENT_ARCHIVE_CONTRACT,
3085
+ exports.CONTENT_RESTORE_CONTRACT,
3086
+ exports.CONTENT_RETRY_CONTRACT,
3087
+ exports.CONTENT_DELETE_CONTRACT,
3088
+ exports.CONTENT_SET_INTENDED_PUBLISH_TIME_CONTRACT,
3089
+ exports.MEDIA_LIST_CONTRACT,
3090
+ exports.MEDIA_LIST_FOLDERS_CONTRACT,
3091
+ exports.MEDIA_GET_FOLDER_CONTRACT,
3092
+ exports.MEDIA_GET_FOLDER_PATH_CONTRACT,
3093
+ exports.MEDIA_LIST_LABELS_CONTRACT,
3094
+ exports.MEDIA_GET_CONTRACT,
3095
+ exports.MEDIA_GET_USAGE_HISTORY_CONTRACT,
3096
+ exports.ANALYTICS_GET_SUMMARY_CONTRACT,
3097
+ exports.ANALYTICS_GET_AGGREGATE_CONTRACT,
3098
+ exports.ANALYTICS_GET_HEALTH_CONTRACT,
3099
+ exports.ANALYTICS_GET_POSTS_CONTRACT,
3100
+ exports.ANALYTICS_GET_POSTS_AGGREGATE_CONTRACT,
3101
+ exports.ANALYTICS_GET_POST_CONTRACT,
3102
+ exports.ANALYTICS_GET_DEMOGRAPHICS_CONTRACT
3103
+ ];
3104
+ }
3105
+ });
2
3106
 
3
3107
  // src/index.ts
4
3108
  import { readFileSync as readFileSync2, realpathSync } from "fs";
@@ -185,10 +3289,10 @@ function cleanBaseUrl(value) {
185
3289
  }
186
3290
  function resolveConfig(command, env = process.env) {
187
3291
  const options = command?.optsWithGlobals?.() ?? {};
188
- const envApiUrl = env.MAEVE_API_URL ?? env.EZIBREEZY_API_URL;
3292
+ const envApiUrl = env.MAEVE_API_URL;
189
3293
  const apiUrl = options.apiUrl || envApiUrl || DEFAULT_API_URL;
190
3294
  const namedEnvApiKey = options.apiKeyEnv ? env[options.apiKeyEnv] : void 0;
191
- const defaultEnvApiKey = options.apiKeyEnv ? void 0 : env.MAEVE_API_KEY ?? env.EZIBREEZY_API_KEY;
3295
+ const defaultEnvApiKey = options.apiKeyEnv ? void 0 : env.MAEVE_API_KEY;
192
3296
  const apiKey = options.apiKey || namedEnvApiKey || defaultEnvApiKey;
193
3297
  const cleanApiUrl = cleanBaseUrl(apiUrl);
194
3298
  const storedCredential = getStoredCredential(cleanApiUrl, getCredentialFilePath(env));
@@ -488,7 +3592,7 @@ function registerAnalyticsCommands(program) {
488
3592
  })
489
3593
  );
490
3594
  });
491
- addConnectionOptions(program.command("analytics:report")).description("Generate an team-plan analytics PDF report.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption(
3595
+ addConnectionOptions(program.command("analytics:report")).description("Generate a standard-plan analytics PDF report.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption(
492
3596
  "--provider <provider>",
493
3597
  "Report provider: instagram, facebook, youtube, tiktok, pinterest, or threads."
494
3598
  ).requiredOption("--json <file>", "JSON file containing report integration IDs and report options.").requiredOption("--output <file>", "PDF output file.").option("--yes", "Confirm report generation.").action(
@@ -695,7 +3799,7 @@ function registerAuthCommands(program) {
695
3799
 
696
3800
  // src/commands/boosts.ts
697
3801
  function registerBoostCommands(program) {
698
- addConnectionOptions(program.command("boosts:list")).description("List boosts for a workspace. Requires team plan.").requiredOption("-w, --workspace <id>", "Workspace ID.").option("--content-ids <ids>", "Comma-separated content IDs to filter by.").option("--statuses <statuses>", "Comma-separated statuses: creating, active, paused, completed, error.").action(async (options, command) => {
3802
+ addConnectionOptions(program.command("boosts:list")).description("List boosts for a workspace. Requires standard plan.").requiredOption("-w, --workspace <id>", "Workspace ID.").option("--content-ids <ids>", "Comma-separated content IDs to filter by.").option("--statuses <statuses>", "Comma-separated statuses: creating, active, paused, completed, error.").action(async (options, command) => {
699
3803
  const client = createApiClient(resolveConfig(command));
700
3804
  writeRawJson(
701
3805
  await client.request("GET", `/v1/workspaces/${options.workspace}/boosts`, {
@@ -703,21 +3807,21 @@ function registerBoostCommands(program) {
703
3807
  })
704
3808
  );
705
3809
  });
706
- addConnectionOptions(program.command("boosts:get")).description("Read one boost. Requires team plan.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--id <boostId>", "Boost ID.").action(async (options, command) => {
3810
+ addConnectionOptions(program.command("boosts:get")).description("Read one boost. Requires standard plan.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--id <boostId>", "Boost ID.").action(async (options, command) => {
707
3811
  const client = createApiClient(resolveConfig(command));
708
3812
  writeRawJson(await client.request("GET", `/v1/workspaces/${options.workspace}/boosts/${options.id}`));
709
3813
  });
710
- addConnectionOptions(program.command("boosts:performance")).description("Refresh and read boost performance. Requires team plan.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--id <boostId>", "Boost ID.").action(async (options, command) => {
3814
+ addConnectionOptions(program.command("boosts:performance")).description("Refresh and read boost performance. Requires standard plan.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--id <boostId>", "Boost ID.").action(async (options, command) => {
711
3815
  const client = createApiClient(resolveConfig(command));
712
3816
  writeRawJson(await client.request("GET", `/v1/workspaces/${options.workspace}/boosts/${options.id}/performance`));
713
3817
  });
714
- addConnectionOptions(program.command("boosts:ad-accounts")).description("List available Meta ad accounts for an integration. Requires team plan.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("-i, --integration <id>", "Integration ID.").action(async (options, command) => {
3818
+ addConnectionOptions(program.command("boosts:ad-accounts")).description("List available Meta ad accounts for an integration. Requires standard plan.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("-i, --integration <id>", "Integration ID.").action(async (options, command) => {
715
3819
  const client = createApiClient(resolveConfig(command));
716
3820
  writeRawJson(
717
3821
  await client.request("GET", `/v1/workspaces/${options.workspace}/boosts/ad-accounts/${options.integration}`)
718
3822
  );
719
3823
  });
720
- addConnectionOptions(program.command("boosts:boosted-content-ids")).description("List active boosted content IDs. Requires team plan.").requiredOption("-w, --workspace <id>", "Workspace ID.").option("--content-ids <ids>", "Comma-separated content IDs to filter by.").action(async (options, command) => {
3824
+ addConnectionOptions(program.command("boosts:boosted-content-ids")).description("List active boosted content IDs. Requires standard plan.").requiredOption("-w, --workspace <id>", "Workspace ID.").option("--content-ids <ids>", "Comma-separated content IDs to filter by.").action(async (options, command) => {
721
3825
  const client = createApiClient(resolveConfig(command));
722
3826
  writeRawJson(
723
3827
  await client.request("GET", `/v1/workspaces/${options.workspace}/boosts/boosted-content-ids`, {
@@ -725,7 +3829,7 @@ function registerBoostCommands(program) {
725
3829
  })
726
3830
  );
727
3831
  });
728
- addConnectionOptions(program.command("boosts:by-content")).description("Read the boost for one published content item. Requires team plan.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--content <contentId>", "Published content ID.").action(async (options, command) => {
3832
+ addConnectionOptions(program.command("boosts:by-content")).description("Read the boost for one published content item. Requires standard plan.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--content <contentId>", "Published content ID.").action(async (options, command) => {
729
3833
  const client = createApiClient(resolveConfig(command));
730
3834
  writeRawJson(await client.request("GET", `/v1/workspaces/${options.workspace}/boosts/content/${options.content}`));
731
3835
  });
@@ -1076,7 +4180,7 @@ var reviewLifecycleResponseSchema = z3.object({
1076
4180
 
1077
4181
  // src/commands/client-reviews.ts
1078
4182
  function registerClientReviewCommands(program) {
1079
- addConnectionOptions(program.command("client-reviews:create")).description("Create a client review batch. Requires team plan and client review send capability.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--json <file>", "JSON file containing the client review batch payload.").action(async (options, command) => {
4183
+ addConnectionOptions(program.command("client-reviews:create")).description("Create a client review batch. Requires standard plan and client review send capability.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--json <file>", "JSON file containing the client review batch payload.").action(async (options, command) => {
1080
4184
  const payload = clientReviewCreateSchema.parse(await readJsonFile(options.json));
1081
4185
  const client = createApiClient(resolveConfig(command));
1082
4186
  writeRawJson(
@@ -1086,7 +4190,7 @@ function registerClientReviewCommands(program) {
1086
4190
  );
1087
4191
  });
1088
4192
  addConnectionOptions(program.command("client-reviews:open")).description(
1089
- "List open client review batches that have not had links sent. Requires team plan and client review read capability."
4193
+ "List open client review batches that have not had links sent. Requires standard plan and client review read capability."
1090
4194
  ).requiredOption("-w, --workspace <id>", "Workspace ID.").option("--workflow-mode <mode>", "Workflow mode: client or internal_client.").action(async (options, command) => {
1091
4195
  const client = createApiClient(resolveConfig(command));
1092
4196
  writeRawJson(
@@ -1095,7 +4199,7 @@ function registerClientReviewCommands(program) {
1095
4199
  })
1096
4200
  );
1097
4201
  });
1098
- addConnectionOptions(program.command("client-reviews:get")).description("Get one client review batch. Requires team plan.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--batch <batchId>", "Client review batch ID.").action(async (options, command) => {
4202
+ addConnectionOptions(program.command("client-reviews:get")).description("Get one client review batch. Requires standard plan.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--batch <batchId>", "Client review batch ID.").action(async (options, command) => {
1099
4203
  const client = createApiClient(resolveConfig(command));
1100
4204
  writeRawJson(
1101
4205
  await client.request(
@@ -1104,7 +4208,9 @@ function registerClientReviewCommands(program) {
1104
4208
  )
1105
4209
  );
1106
4210
  });
1107
- addConnectionOptions(program.command("client-reviews:add-post")).description("Add content to an open client review batch. Requires team plan and client review send capability.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--batch <batchId>", "Client review batch ID.").requiredOption("--json <file>", "JSON file containing contentId.").action(async (options, command) => {
4211
+ addConnectionOptions(program.command("client-reviews:add-post")).description(
4212
+ "Add content to an open client review batch. Requires standard plan and client review send capability."
4213
+ ).requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--batch <batchId>", "Client review batch ID.").requiredOption("--json <file>", "JSON file containing contentId.").action(async (options, command) => {
1108
4214
  const payload = clientReviewPostMutationSchema.parse(await readJsonFile(options.json));
1109
4215
  const client = createApiClient(resolveConfig(command));
1110
4216
  writeRawJson(
@@ -1116,7 +4222,7 @@ function registerClientReviewCommands(program) {
1116
4222
  );
1117
4223
  });
1118
4224
  addConnectionOptions(program.command("client-reviews:remove-post")).description(
1119
- "Remove content from an open client review batch. Requires team plan and client review send capability."
4225
+ "Remove content from an open client review batch. Requires standard plan and client review send capability."
1120
4226
  ).requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--batch <batchId>", "Client review batch ID.").requiredOption("--json <file>", "JSON file containing contentId.").action(async (options, command) => {
1121
4227
  const payload = clientReviewPostMutationSchema.parse(await readJsonFile(options.json));
1122
4228
  const client = createApiClient(resolveConfig(command));
@@ -1129,7 +4235,7 @@ function registerClientReviewCommands(program) {
1129
4235
  );
1130
4236
  });
1131
4237
  addConnectionOptions(program.command("client-reviews:send")).description(
1132
- "Send a client review batch. Requires team plan and client review send capability; may notify reviewers."
4238
+ "Send a client review batch. Requires standard plan and client review send capability; may notify reviewers."
1133
4239
  ).requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--batch <batchId>", "Client review batch ID.").option("--yes", "Confirm reviewer notifications.").action(async (options, command) => {
1134
4240
  if (!options.yes) {
1135
4241
  throw new CliError("client-reviews:send requires --yes because it may notify reviewers.", {
@@ -1145,7 +4251,7 @@ function registerClientReviewCommands(program) {
1145
4251
  );
1146
4252
  });
1147
4253
  addConnectionOptions(program.command("client-reviews:resend")).description(
1148
- "Resend a client review batch. Requires team plan and client review send capability; may notify reviewers."
4254
+ "Resend a client review batch. Requires standard plan and client review send capability; may notify reviewers."
1149
4255
  ).requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--batch <batchId>", "Client review batch ID.").option("--yes", "Confirm reviewer notifications.").action(async (options, command) => {
1150
4256
  if (!options.yes) {
1151
4257
  throw new CliError("client-reviews:resend requires --yes because it may notify reviewers.", {
@@ -1160,7 +4266,7 @@ function registerClientReviewCommands(program) {
1160
4266
  )
1161
4267
  );
1162
4268
  });
1163
- addConnectionOptions(program.command("client-reviews:cancel")).description("Cancel a client review batch. Requires team plan and client review send capability.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--batch <batchId>", "Client review batch ID.").action(async (options, command) => {
4269
+ addConnectionOptions(program.command("client-reviews:cancel")).description("Cancel a client review batch. Requires standard plan and client review send capability.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--batch <batchId>", "Client review batch ID.").action(async (options, command) => {
1164
4270
  const client = createApiClient(resolveConfig(command));
1165
4271
  writeRawJson(
1166
4272
  await client.request(
@@ -1169,7 +4275,7 @@ function registerClientReviewCommands(program) {
1169
4275
  )
1170
4276
  );
1171
4277
  });
1172
- addConnectionOptions(program.command("client-reviews:override")).description("Override a client review batch item. Requires team plan and content review override capability.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--batch <batchId>", "Client review batch ID.").requiredOption("--json <file>", "JSON file containing contentId and reason.").action(async (options, command) => {
4278
+ addConnectionOptions(program.command("client-reviews:override")).description("Override a client review batch item. Requires standard plan and content review override capability.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--batch <batchId>", "Client review batch ID.").requiredOption("--json <file>", "JSON file containing contentId and reason.").action(async (options, command) => {
1173
4279
  const payload = clientReviewOverrideSchema.parse(await readJsonFile(options.json));
1174
4280
  const client = createApiClient(resolveConfig(command));
1175
4281
  writeRawJson(
@@ -1180,7 +4286,7 @@ function registerClientReviewCommands(program) {
1180
4286
  )
1181
4287
  );
1182
4288
  });
1183
- addConnectionOptions(program.command("client-reviews:update-participant")).description("Update a client review participant. Requires team plan and client review send capability.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--batch <batchId>", "Client review batch ID.").requiredOption("--json <file>", "JSON file containing participantId and email.").action(async (options, command) => {
4289
+ addConnectionOptions(program.command("client-reviews:update-participant")).description("Update a client review participant. Requires standard plan and client review send capability.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--batch <batchId>", "Client review batch ID.").requiredOption("--json <file>", "JSON file containing participantId and email.").action(async (options, command) => {
1184
4290
  const payload = clientReviewParticipantUpdateSchema.parse(await readJsonFile(options.json));
1185
4291
  const client = createApiClient(resolveConfig(command));
1186
4292
  writeRawJson(
@@ -1192,7 +4298,7 @@ function registerClientReviewCommands(program) {
1192
4298
  );
1193
4299
  });
1194
4300
  addConnectionOptions(program.command("client-reviews:comment")).description(
1195
- "Add an internal client-review thread comment. Requires team plan and client review comment capability."
4301
+ "Add an internal client-review thread comment. Requires standard plan and client review comment capability."
1196
4302
  ).requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--batch <batchId>", "Client review batch ID.").requiredOption("--json <file>", "JSON file containing contentId and body or attachmentId.").action(async (options, command) => {
1197
4303
  const payload = clientReviewCommentSchema.parse(await readJsonFile(options.json));
1198
4304
  const client = createApiClient(resolveConfig(command));
@@ -1210,6 +4316,7 @@ function registerClientReviewCommands(program) {
1210
4316
  import { randomUUID } from "crypto";
1211
4317
 
1212
4318
  // src/content-schema.ts
4319
+ var import_tool_contracts = __toESM(require_dist(), 1);
1213
4320
  import { z as z4 } from "zod";
1214
4321
  var uuid4 = z4.string().uuid();
1215
4322
  var isoWithTimezone = z4.string().refine(
@@ -1400,6 +4507,12 @@ var updateContentSchema = createContentBaseSchema.omit({ intent: true }).partial
1400
4507
  var scheduleContentSchema = z4.object({
1401
4508
  scheduledAt: isoWithTimezone
1402
4509
  });
4510
+ var intendedPublishTimeInputSchema = import_tool_contracts.contentSetIntendedPublishTimeInputSchema;
4511
+ var cancelRecurringSeriesSchema = z4.object({
4512
+ scope: z4.literal("future"),
4513
+ effectiveOccurrenceId: uuid4,
4514
+ expectedVersion: z4.number().int().min(1).optional()
4515
+ }).strict();
1403
4516
  var updateContentNotesSchema = z4.object({
1404
4517
  notes: z4.string().max(1e5)
1405
4518
  });
@@ -1477,14 +4590,14 @@ function registerContentCommands(program) {
1477
4590
  );
1478
4591
  });
1479
4592
  addConnectionOptions(program.command("content:intended-time")).description("Set intended publish time for draft or pending approval content without scheduling it.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--id <contentId>", "Content ID.").requiredOption("--scheduled-at <iso>", "ISO8601 timestamp with explicit timezone.").action(async (options, command) => {
1480
- const payload = scheduleContentSchema.parse({ scheduledAt: options.scheduledAt });
4593
+ const input = intendedPublishTimeInputSchema.parse({ contentId: options.id, scheduledAt: options.scheduledAt });
1481
4594
  const client = createApiClient(resolveConfig(command));
1482
4595
  writeRawJson(
1483
4596
  await client.request(
1484
4597
  "PATCH",
1485
- `/v1/workspaces/${options.workspace}/content/${options.id}/intended-publish-time`,
4598
+ `/v1/workspaces/${options.workspace}/content/${input.contentId}/intended-publish-time`,
1486
4599
  {
1487
- body: payload
4600
+ body: { scheduledAt: input.scheduledAt }
1488
4601
  }
1489
4602
  )
1490
4603
  );
@@ -1551,11 +4664,11 @@ function registerContentCommands(program) {
1551
4664
  const client = createApiClient(resolveConfig(command));
1552
4665
  writeRawJson(await client.request("GET", `/v1/workspaces/${options.workspace}/content/failed-count`));
1553
4666
  });
1554
- addConnectionOptions(program.command("content:pending-approval-count")).description("Get the pending approval count for a workspace. Requires team plan.").requiredOption("-w, --workspace <id>", "Workspace ID.").action(async (options, command) => {
4667
+ addConnectionOptions(program.command("content:pending-approval-count")).description("Get the pending approval count for a workspace. Requires standard plan.").requiredOption("-w, --workspace <id>", "Workspace ID.").action(async (options, command) => {
1555
4668
  const client = createApiClient(resolveConfig(command));
1556
4669
  writeRawJson(await client.request("GET", `/v1/workspaces/${options.workspace}/content/pending-approval-count`));
1557
4670
  });
1558
- addConnectionOptions(program.command("content:approval-history")).description("List approval history for a workspace. Requires team plan.").requiredOption("-w, --workspace <id>", "Workspace ID.").option("--limit <number>", "Page size.").option("--cursor <cursor>", "Pagination cursor.").option("--search <text>", "Search approval history.").option("--workflow-path <path>", "Workflow path: all, internal, client, or internal_client.").option("--outcome <outcome>", "Outcome filter.").option("--platform <platform>", "Platform filter.").option("--reviewer <text>", "Reviewer filter.").option("--date-from <iso>", "ISO8601 start date.").option("--date-to <iso>", "ISO8601 end date.").action(async (options, command) => {
4671
+ addConnectionOptions(program.command("content:approval-history")).description("List approval history for a workspace. Requires standard plan.").requiredOption("-w, --workspace <id>", "Workspace ID.").option("--limit <number>", "Page size.").option("--cursor <cursor>", "Pagination cursor.").option("--search <text>", "Search approval history.").option("--workflow-path <path>", "Workflow path: all, internal, client, or internal_client.").option("--outcome <outcome>", "Outcome filter.").option("--platform <platform>", "Platform filter.").option("--reviewer <text>", "Reviewer filter.").option("--date-from <iso>", "ISO8601 start date.").option("--date-to <iso>", "ISO8601 end date.").action(async (options, command) => {
1559
4672
  const client = createApiClient(resolveConfig(command));
1560
4673
  writeRawJson(
1561
4674
  await client.request("GET", `/v1/workspaces/${options.workspace}/content/approval-history`, {
@@ -1573,7 +4686,7 @@ function registerContentCommands(program) {
1573
4686
  })
1574
4687
  );
1575
4688
  });
1576
- addConnectionOptions(program.command("content:approval-history:client-batch")).description("Get client batch approval history detail. Requires team plan.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--batch <batchId>", "Client review batch ID.").action(async (options, command) => {
4689
+ addConnectionOptions(program.command("content:approval-history:client-batch")).description("Get client batch approval history detail. Requires standard plan.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--batch <batchId>", "Client review batch ID.").action(async (options, command) => {
1577
4690
  const client = createApiClient(resolveConfig(command));
1578
4691
  writeRawJson(
1579
4692
  await client.request(
@@ -1582,7 +4695,7 @@ function registerContentCommands(program) {
1582
4695
  )
1583
4696
  );
1584
4697
  });
1585
- addConnectionOptions(program.command("content:approval-history:internal")).description("Get internal approval history detail. Requires team plan.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--record <recordId>", "Approval record ID.").action(async (options, command) => {
4698
+ addConnectionOptions(program.command("content:approval-history:internal")).description("Get internal approval history detail. Requires standard plan.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--record <recordId>", "Approval record ID.").action(async (options, command) => {
1586
4699
  const client = createApiClient(resolveConfig(command));
1587
4700
  writeRawJson(
1588
4701
  await client.request(
@@ -1592,7 +4705,7 @@ function registerContentCommands(program) {
1592
4705
  );
1593
4706
  });
1594
4707
  addConnectionOptions(program.command("content:comment-attachments:init")).description(
1595
- "Initialize an approval comment attachment upload. Requires team plan and content review comment capability."
4708
+ "Initialize an approval comment attachment upload. Requires standard plan and content review comment capability."
1596
4709
  ).requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--json <file>", "JSON file containing the attachment upload payload.").action(async (options, command) => {
1597
4710
  const payload = approvalAttachmentInitSchema.parse(await readJsonFile(options.json));
1598
4711
  const client = createApiClient(resolveConfig(command));
@@ -1603,7 +4716,7 @@ function registerContentCommands(program) {
1603
4716
  );
1604
4717
  });
1605
4718
  addConnectionOptions(program.command("content:comment-attachments:complete")).description(
1606
- "Complete an approval comment attachment upload. Requires team plan and content review comment capability."
4719
+ "Complete an approval comment attachment upload. Requires standard plan and content review comment capability."
1607
4720
  ).requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--attachment <attachmentId>", "Attachment ID.").action(async (options, command) => {
1608
4721
  const client = createApiClient(resolveConfig(command));
1609
4722
  writeRawJson(
@@ -1614,7 +4727,7 @@ function registerContentCommands(program) {
1614
4727
  );
1615
4728
  });
1616
4729
  addConnectionOptions(program.command("content:comment-attachments:abort")).description(
1617
- "Abort an approval comment attachment upload. Requires team plan and content review comment capability."
4730
+ "Abort an approval comment attachment upload. Requires standard plan and content review comment capability."
1618
4731
  ).requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--attachment <attachmentId>", "Attachment ID.").action(async (options, command) => {
1619
4732
  const client = createApiClient(resolveConfig(command));
1620
4733
  writeRawJson(
@@ -1624,7 +4737,9 @@ function registerContentCommands(program) {
1624
4737
  )
1625
4738
  );
1626
4739
  });
1627
- addConnectionOptions(program.command("content:activity:react")).description("Add a reaction to an approval activity. Requires team plan and content review comment capability.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--activity <activityId>", "Activity ID.").requiredOption("--json <file>", "JSON file containing emoji.").action(async (options, command) => {
4740
+ addConnectionOptions(program.command("content:activity:react")).description(
4741
+ "Add a reaction to an approval activity. Requires standard plan and content review comment capability."
4742
+ ).requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--activity <activityId>", "Activity ID.").requiredOption("--json <file>", "JSON file containing emoji.").action(async (options, command) => {
1628
4743
  const payload = approvalReactionSchema.parse(await readJsonFile(options.json));
1629
4744
  const client = createApiClient(resolveConfig(command));
1630
4745
  writeRawJson(
@@ -1638,7 +4753,7 @@ function registerContentCommands(program) {
1638
4753
  );
1639
4754
  });
1640
4755
  addConnectionOptions(program.command("content:activity:unreact")).description(
1641
- "Remove a reaction from an approval activity. Requires team plan and content review comment capability."
4756
+ "Remove a reaction from an approval activity. Requires standard plan and content review comment capability."
1642
4757
  ).requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--activity <activityId>", "Activity ID.").requiredOption("--emoji <emoji>", "Reaction emoji to remove.").action(async (options, command) => {
1643
4758
  const client = createApiClient(resolveConfig(command));
1644
4759
  writeRawJson(
@@ -1649,7 +4764,7 @@ function registerContentCommands(program) {
1649
4764
  );
1650
4765
  });
1651
4766
  addConnectionOptions(program.command("content:request-approval")).description(
1652
- "Request internal approval for a content item. Requires team plan and content review request capability; may notify approvers."
4767
+ "Request internal approval for a content item. Requires standard plan and content review request capability; may notify approvers."
1653
4768
  ).requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--id <contentId>", "Content ID.").requiredOption("--json <file>", "JSON file containing approverIds and policy.").option("--yes", "Confirm approver notifications.").action(async (options, command) => {
1654
4769
  if (!options.yes) {
1655
4770
  throw new CliError("content:request-approval requires --yes because it may notify approvers.", {
@@ -1664,7 +4779,7 @@ function registerContentCommands(program) {
1664
4779
  })
1665
4780
  );
1666
4781
  });
1667
- addConnectionOptions(program.command("content:decision")).description("Submit an internal approval decision. Requires team plan and content review decision capability.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--id <contentId>", "Content ID.").requiredOption("--json <file>", "JSON file containing decision, optional override, and reason.").action(async (options, command) => {
4782
+ addConnectionOptions(program.command("content:decision")).description("Submit an internal approval decision. Requires standard plan and content review decision capability.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--id <contentId>", "Content ID.").requiredOption("--json <file>", "JSON file containing decision, optional override, and reason.").action(async (options, command) => {
1668
4783
  const payload = approvalDecisionSchema.parse(await readJsonFile(options.json));
1669
4784
  const client = createApiClient(resolveConfig(command));
1670
4785
  writeRawJson(
@@ -1673,12 +4788,14 @@ function registerContentCommands(program) {
1673
4788
  })
1674
4789
  );
1675
4790
  });
1676
- addConnectionOptions(program.command("content:withdraw")).description("Withdraw an internal approval request. Requires team plan and content review withdraw capability.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--id <contentId>", "Content ID.").action(async (options, command) => {
4791
+ addConnectionOptions(program.command("content:withdraw")).description(
4792
+ "Withdraw an internal approval request. Requires standard plan and content review withdraw capability."
4793
+ ).requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--id <contentId>", "Content ID.").action(async (options, command) => {
1677
4794
  const client = createApiClient(resolveConfig(command));
1678
4795
  writeRawJson(await client.request("POST", `/v1/workspaces/${options.workspace}/content/${options.id}/withdraw`));
1679
4796
  });
1680
4797
  addConnectionOptions(program.command("content:resubmit")).description(
1681
- "Resubmit rejected content for approval. Requires team plan and content review request capability; may notify approvers."
4798
+ "Resubmit rejected content for approval. Requires standard plan and content review request capability; may notify approvers."
1682
4799
  ).requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--id <contentId>", "Content ID.").requiredOption("--json <file>", "JSON file containing approverIds and policy.").option("--yes", "Confirm approver notifications.").action(async (options, command) => {
1683
4800
  if (!options.yes) {
1684
4801
  throw new CliError("content:resubmit requires --yes because it may notify approvers.", {
@@ -1693,12 +4810,12 @@ function registerContentCommands(program) {
1693
4810
  })
1694
4811
  );
1695
4812
  });
1696
- addConnectionOptions(program.command("content:history")).description("Get approval activity history for one content item. Requires team plan.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--id <contentId>", "Content ID.").action(async (options, command) => {
4813
+ addConnectionOptions(program.command("content:history")).description("Get approval activity history for one content item. Requires standard plan.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--id <contentId>", "Content ID.").action(async (options, command) => {
1697
4814
  const client = createApiClient(resolveConfig(command));
1698
4815
  writeRawJson(await client.request("GET", `/v1/workspaces/${options.workspace}/content/${options.id}/history`));
1699
4816
  });
1700
4817
  addConnectionOptions(program.command("content:comment")).description(
1701
- "Add an internal approval comment to one content item. Requires team plan and content review comment capability."
4818
+ "Add an internal approval comment to one content item. Requires standard plan and content review comment capability."
1702
4819
  ).requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--id <contentId>", "Content ID.").requiredOption("--json <file>", "JSON file containing body or attachmentId.").action(async (options, command) => {
1703
4820
  const payload = approvalCommentSchema.parse(await readJsonFile(options.json));
1704
4821
  const client = createApiClient(resolveConfig(command));
@@ -1708,7 +4825,7 @@ function registerContentCommands(program) {
1708
4825
  })
1709
4826
  );
1710
4827
  });
1711
- addConnectionOptions(program.command("content:reopen-client-review")).description("Reopen client review for one content item. Requires team plan and client review send capability.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--id <contentId>", "Content ID.").action(async (options, command) => {
4828
+ addConnectionOptions(program.command("content:reopen-client-review")).description("Reopen client review for one content item. Requires standard plan and client review send capability.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--id <contentId>", "Content ID.").action(async (options, command) => {
1712
4829
  const client = createApiClient(resolveConfig(command));
1713
4830
  writeRawJson(
1714
4831
  await client.request("POST", `/v1/workspaces/${options.workspace}/content/${options.id}/reopen-client-review`)
@@ -1719,6 +4836,57 @@ function registerContentCommands(program) {
1719
4836
  await client.request("DELETE", `/v1/workspaces/${options.workspace}/content/${options.id}`);
1720
4837
  writeJson({ id: options.id, deleted: true });
1721
4838
  });
4839
+ addConnectionOptions(program.command("content:recurring-occurrence:cancel")).description(
4840
+ "Cancel one occurrence of a recurring series and its linked content. Find the occurrence ID in recurringMetadata on content:list."
4841
+ ).requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--occurrence <occurrenceId>", "Recurring occurrence ID.").option("--yes", "Confirm cancelling the occurrence.").action(async (options, command) => {
4842
+ if (!options.yes) {
4843
+ throw new CliError(
4844
+ "content:recurring-occurrence:cancel requires --yes because it removes scheduled publishing work.",
4845
+ {
4846
+ code: "INVALID_OPTIONS"
4847
+ }
4848
+ );
4849
+ }
4850
+ const client = createApiClient(resolveConfig(command));
4851
+ writeRawJson(
4852
+ await client.request(
4853
+ "POST",
4854
+ `/v1/workspaces/${options.workspace}/content/recurring-occurrences/${options.occurrence}/cancel`,
4855
+ {
4856
+ body: {}
4857
+ }
4858
+ )
4859
+ );
4860
+ });
4861
+ addConnectionOptions(program.command("content:recurring-series:cancel")).description(
4862
+ "Cancel a recurring series and every not-yet-published occurrence from the effective occurrence forward. Find the series and occurrence IDs in recurringMetadata on content:list."
4863
+ ).requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--series <seriesId>", "Recurring series ID.").requiredOption("--effective-occurrence <occurrenceId>", "Occurrence the cancellation takes effect from.").option("--expected-version <number>", "Fail if the series version has moved past this value.").option("--yes", "Confirm cancelling the series.").action(
4864
+ async (options, command) => {
4865
+ if (!options.yes) {
4866
+ throw new CliError(
4867
+ "content:recurring-series:cancel requires --yes because it removes scheduled publishing work.",
4868
+ {
4869
+ code: "INVALID_OPTIONS"
4870
+ }
4871
+ );
4872
+ }
4873
+ const payload = cancelRecurringSeriesSchema.parse({
4874
+ scope: "future",
4875
+ effectiveOccurrenceId: options.effectiveOccurrence,
4876
+ ...options.expectedVersion !== void 0 ? { expectedVersion: Number(options.expectedVersion) } : {}
4877
+ });
4878
+ const client = createApiClient(resolveConfig(command));
4879
+ writeRawJson(
4880
+ await client.request(
4881
+ "POST",
4882
+ `/v1/workspaces/${options.workspace}/content/recurring-series/${options.series}/cancel`,
4883
+ {
4884
+ body: payload
4885
+ }
4886
+ )
4887
+ );
4888
+ }
4889
+ );
1722
4890
  }
1723
4891
 
1724
4892
  // src/grid-planner-schema.ts
@@ -2000,11 +5168,29 @@ var inboxNoteSchema = z7.object({
2000
5168
  var inboxModerateSchema = z7.object({
2001
5169
  action: z7.enum(["hide", "unhide", "delete"])
2002
5170
  });
5171
+ var inboxTagCreateSchema = z7.object({
5172
+ name: z7.string().trim().min(1).max(50),
5173
+ color: z7.string().regex(/^#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?$/).nullable().optional(),
5174
+ sortOrder: z7.number().int().min(0).max(1e4).optional()
5175
+ }).strict();
5176
+ var inboxTagUpdateSchema = z7.object({
5177
+ name: z7.string().trim().min(1).max(50).optional(),
5178
+ color: z7.string().regex(/^#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?$/).nullable().optional(),
5179
+ sortOrder: z7.number().int().min(0).max(1e4).optional()
5180
+ }).strict();
5181
+ var inboxTagsReorderSchema = z7.object({
5182
+ tagIds: z7.array(uuid5).max(100)
5183
+ }).strict();
5184
+ var inboxThreadTagsSchema = z7.object({
5185
+ tagIds: z7.array(uuid5).max(20)
5186
+ }).strict();
2003
5187
  var inboxMarkAllReadSchema = z7.object({
2004
5188
  platform: z7.enum(["instagram", "facebook", "threads"]).optional(),
2005
5189
  status: z7.enum(["open", "archived", "all"]).optional(),
2006
5190
  integrationId: z7.string().min(1).optional(),
2007
- messageType: z7.enum(["comment", "dm", "review", "mention"]).optional()
5191
+ messageType: z7.enum(["comment", "dm", "review", "mention"]).optional(),
5192
+ tagIds: z7.array(uuid5).max(20).optional(),
5193
+ tagMatch: z7.enum(["any", "all"]).optional()
2008
5194
  });
2009
5195
  var inboxResolveSchema = z7.object({
2010
5196
  reason: z7.enum(["manual", "reply_sent", "moderated", "handled_natively", "handled_offline", "no_response_needed"]).optional(),
@@ -2018,6 +5204,8 @@ var inboxResolveAllSchema = z7.object({
2018
5204
  search: z7.string().max(200).optional(),
2019
5205
  read: z7.enum(["read", "unread", "all"]).optional(),
2020
5206
  resolution: z7.enum(["resolved", "unresolved", "all"]).optional(),
5207
+ tagIds: z7.array(uuid5).max(20).optional(),
5208
+ tagMatch: z7.enum(["any", "all"]).optional(),
2021
5209
  page: z7.number().int().min(1).optional(),
2022
5210
  limit: z7.number().int().min(1).max(50).optional(),
2023
5211
  threadIds: z7.array(uuid5).max(50).optional(),
@@ -2026,8 +5214,14 @@ var inboxResolveAllSchema = z7.object({
2026
5214
  }).strict();
2027
5215
 
2028
5216
  // src/commands/inbox.ts
5217
+ function collectOption(value, previous = []) {
5218
+ return [...previous, value];
5219
+ }
5220
+ function parseOptionalNumber(value) {
5221
+ return value === void 0 ? void 0 : Number(value);
5222
+ }
2029
5223
  function registerInboxCommands(program) {
2030
- addConnectionOptions(program.command("inbox:threads")).description("List inbox threads for a workspace.").requiredOption("-w, --workspace <id>", "Workspace ID.").option("--status <status>", "Thread status: open, archived, or all.").option("--read <state>", "Read state: read, unread, or all.").option("--platform <platform>", "Platform filter.").option("--integration <id>", "Integration ID filter.").option("--message-type <type>", "Message type filter.").option("--search <text>", "Search text.").option("--page <number>", "Page number.").option("--limit <number>", "Page size.").action(
5224
+ addConnectionOptions(program.command("inbox:threads")).description("List inbox threads for a workspace.").requiredOption("-w, --workspace <id>", "Workspace ID.").option("--status <status>", "Thread status: open, archived, or all.").option("--read <state>", "Read state: read, unread, or all.").option("--platform <platform>", "Platform filter.").option("--integration <id>", "Integration ID filter.").option("--message-type <type>", "Message type filter.").option("--search <text>", "Search text.").option("--tag <id>", "Inbox tag ID filter. Can be passed multiple times.", collectOption, []).option("--tag-match <mode>", "Tag match mode: any or all.").option("--page <number>", "Page number.").option("--limit <number>", "Page size.").action(
2031
5225
  async (options, command) => {
2032
5226
  const client = createApiClient(resolveConfig(command));
2033
5227
  writeRawJson(
@@ -2039,6 +5233,8 @@ function registerInboxCommands(program) {
2039
5233
  integrationId: options.integration,
2040
5234
  messageType: options.messageType,
2041
5235
  search: options.search,
5236
+ tagIds: options.tag,
5237
+ tagMatch: options.tagMatch,
2042
5238
  page: options.page,
2043
5239
  limit: options.limit
2044
5240
  }
@@ -2046,6 +5242,77 @@ function registerInboxCommands(program) {
2046
5242
  );
2047
5243
  }
2048
5244
  );
5245
+ addConnectionOptions(program.command("inbox:tags")).description("List inbox tags for a workspace.").requiredOption("-w, --workspace <id>", "Workspace ID.").option("--include-archived", "Include archived inbox tags.").action(async (options, command) => {
5246
+ const client = createApiClient(resolveConfig(command));
5247
+ writeRawJson(
5248
+ await client.request("GET", `/v1/workspaces/${options.workspace}/inbox/tags`, {
5249
+ query: { includeArchived: options.includeArchived ? "true" : void 0 }
5250
+ })
5251
+ );
5252
+ });
5253
+ addConnectionOptions(program.command("inbox:tags:create")).description("Create an inbox tag.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--name <name>", "Tag name.").option("--color <hex>", "Tag color, for example #2563eb.").option("--sort-order <number>", "Sort order.").action(
5254
+ async (options, command) => {
5255
+ const payload = inboxTagCreateSchema.parse({
5256
+ name: options.name,
5257
+ color: options.color,
5258
+ sortOrder: parseOptionalNumber(options.sortOrder)
5259
+ });
5260
+ const client = createApiClient(resolveConfig(command));
5261
+ writeRawJson(await client.request("POST", `/v1/workspaces/${options.workspace}/inbox/tags`, { body: payload }));
5262
+ }
5263
+ );
5264
+ addConnectionOptions(program.command("inbox:tags:update")).description("Update an inbox tag.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--tag <tagId>", "Inbox tag ID.").option("--name <name>", "Tag name.").option("--color <hex>", "Tag color, for example #2563eb.").option("--sort-order <number>", "Sort order.").action(
5265
+ async (options, command) => {
5266
+ const payload = inboxTagUpdateSchema.parse({
5267
+ name: options.name,
5268
+ color: options.color,
5269
+ sortOrder: parseOptionalNumber(options.sortOrder)
5270
+ });
5271
+ const client = createApiClient(resolveConfig(command));
5272
+ writeRawJson(
5273
+ await client.request("PATCH", `/v1/workspaces/${options.workspace}/inbox/tags/${options.tag}`, {
5274
+ body: payload
5275
+ })
5276
+ );
5277
+ }
5278
+ );
5279
+ addConnectionOptions(program.command("inbox:tags:archive")).description("Archive an inbox tag.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--tag <tagId>", "Inbox tag ID.").action(async (options, command) => {
5280
+ const client = createApiClient(resolveConfig(command));
5281
+ writeRawJson(
5282
+ await client.request("POST", `/v1/workspaces/${options.workspace}/inbox/tags/${options.tag}/archive`)
5283
+ );
5284
+ });
5285
+ addConnectionOptions(program.command("inbox:tags:restore")).description("Restore an archived inbox tag.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--tag <tagId>", "Inbox tag ID.").action(async (options, command) => {
5286
+ const client = createApiClient(resolveConfig(command));
5287
+ writeRawJson(
5288
+ await client.request("POST", `/v1/workspaces/${options.workspace}/inbox/tags/${options.tag}/restore`)
5289
+ );
5290
+ });
5291
+ addConnectionOptions(program.command("inbox:tags:delete")).description("Delete an inbox tag and remove it from every inbox conversation.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--tag <tagId>", "Inbox tag ID.").option("--yes", "Confirm deleting the tag from every inbox conversation.").action(async (options, command) => {
5292
+ if (!options.yes) {
5293
+ throw new CliError("inbox:tags:delete requires --yes because it removes the tag from every conversation.", {
5294
+ code: "INVALID_OPTIONS"
5295
+ });
5296
+ }
5297
+ const client = createApiClient(resolveConfig(command));
5298
+ writeRawJson(await client.request("DELETE", `/v1/workspaces/${options.workspace}/inbox/tags/${options.tag}`));
5299
+ });
5300
+ addConnectionOptions(program.command("inbox:tags:reorder")).description("Reorder inbox tags from a JSON payload.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--json <file>", "JSON file containing tagIds.").action(async (options, command) => {
5301
+ const payload = inboxTagsReorderSchema.parse(await readJsonFile(options.json));
5302
+ const client = createApiClient(resolveConfig(command));
5303
+ writeRawJson(
5304
+ await client.request("PUT", `/v1/workspaces/${options.workspace}/inbox/tags/reorder`, { body: payload })
5305
+ );
5306
+ });
5307
+ addConnectionOptions(program.command("inbox:tag-thread")).description("Set inbox tags on one thread.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--thread <threadId>", "Inbox thread ID.").option("--tag <id>", "Inbox tag ID. Can be passed multiple times.", collectOption, []).action(async (options, command) => {
5308
+ const payload = inboxThreadTagsSchema.parse({ tagIds: options.tag ?? [] });
5309
+ const client = createApiClient(resolveConfig(command));
5310
+ writeRawJson(
5311
+ await client.request("PUT", `/v1/workspaces/${options.workspace}/inbox/threads/${options.thread}/tags`, {
5312
+ body: payload
5313
+ })
5314
+ );
5315
+ });
2049
5316
  addConnectionOptions(program.command("inbox:messages")).description("List messages for an inbox thread.").requiredOption("-w, --workspace <id>", "Workspace ID.").requiredOption("--thread <threadId>", "Inbox thread ID.").action(async (options, command) => {
2050
5317
  const client = createApiClient(resolveConfig(command));
2051
5318
  writeRawJson(