@contentful/mcp-tools 0.12.3 → 0.12.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +5290 -1145
- package/dist/index.js +2570 -199
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -335,7 +335,12 @@ var RESOURCE_DISPLAY_NAME = {
|
|
|
335
335
|
aiAction: "AI action",
|
|
336
336
|
locale: "locale",
|
|
337
337
|
concept: "concept",
|
|
338
|
-
conceptScheme: "concept scheme"
|
|
338
|
+
conceptScheme: "concept scheme",
|
|
339
|
+
component: "component",
|
|
340
|
+
experience: "experience",
|
|
341
|
+
experienceFragment: "experience fragment",
|
|
342
|
+
experienceTemplate: "experience template",
|
|
343
|
+
dataAssembly: "data assembly"
|
|
339
344
|
};
|
|
340
345
|
function buildConfirmationPreview(resource, id, details, confirmToken) {
|
|
341
346
|
const displayName = RESOURCE_DISPLAY_NAME[resource];
|
|
@@ -2303,141 +2308,61 @@ var ContextStore = class {
|
|
|
2303
2308
|
var contextStore = new ContextStore();
|
|
2304
2309
|
|
|
2305
2310
|
// src/tools/context/instructions.ts
|
|
2306
|
-
var
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
- **
|
|
2316
|
-
- **
|
|
2317
|
-
- **
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
- **
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
- If a user asks to create a field that doesn't match the content type (e.g., "writer" when the content type has "author"), suggest the correct type
|
|
2329
|
-
|
|
2330
|
-
## entry Creation Limits:
|
|
2331
|
-
- A user is only allowed to create/edit/mutate a maximum of 5 (five) entries at a time
|
|
2332
|
-
- For multiple entry creation, use the 'async' parameter (set to true) for better performance
|
|
2333
|
-
- Only use async=true when creating more than one entry in a single conversation
|
|
2334
|
-
|
|
2335
|
-
# Searching for Content
|
|
2336
|
-
|
|
2337
|
-
## Content-Type-First Search Strategy:
|
|
2338
|
-
- **Content-Type-first approach**: When users ask about specific content (e.g., "pricing page", "blog posts"), use get_content_type first to discover relevant content types
|
|
2339
|
-
- This immediately reveals the correct content types and prevents wasted time on failed queries
|
|
2340
|
-
- After understanding the content type, use search_entries to search for content based on the correct content types and field names
|
|
2341
|
-
- If a query returns no results, retry 2-3 times with modified queries by adjusting filters, relaxing constraints, or trying alternative field names
|
|
2342
|
-
- When retrying queries, consider using more general terms, removing specific filters, or checking for typos in field names
|
|
2343
|
-
|
|
2344
|
-
## Handling Multi-Step Queries:
|
|
2345
|
-
- For requests involving related entities (e.g., "Find blog posts by Magnus"), use a multi-step approach
|
|
2346
|
-
- ALWAYS check the content type structure first to understand fields and references
|
|
2347
|
-
- First, query for the referenced entity (e.g., author) to find its ID or confirm its existence
|
|
2348
|
-
- If multiple entities match (e.g., several authors named "Magnus"), query them all and display them to the user
|
|
2349
|
-
- Then use the found ID(s) to query for the primary content (e.g., blog posts referencing that author)
|
|
2350
|
-
- For references in Contentful, remember to use the proper reference format
|
|
2351
|
-
- Verify fields in the content type before constructing queries (single reference vs. array of references)
|
|
2352
|
-
|
|
2353
|
-
## Entry Management:
|
|
2354
|
-
- For entry creation, use create_entry with clear instructions
|
|
2355
|
-
- Use entry_action for operations like publishing, unpublishing, deleting, or discarding entries
|
|
2356
|
-
- Use update_entry for content modifications with AI assistance. Always call get_entry first and pass the returned sys.version to update_entry; this is required and prevents overwriting concurrent changes.
|
|
2357
|
-
- Use patch_entry for precise, direct modifications without AI generation (one operation at a time)
|
|
2358
|
-
- Use transform_entry when preserving rich text formatting is crucial
|
|
2359
|
-
- Use translate_entry specifically for language translation tasks
|
|
2360
|
-
- Use transform_image for AI-powered image operations
|
|
2361
|
-
- Always verify entry existence before attempting to modify it
|
|
2362
|
-
|
|
2363
|
-
# Migration Strategies
|
|
2364
|
-
- Use the space_to_space migration workflow to help a user when they want to migrate content from one space to another. Start this workflow by calling the start_space_to_space_migration tool.
|
|
2365
|
-
- You do not need to fetch content types (ex. list_content_types tool) or entries (ex. search_entries tool) prior to starting the migration workflow. Once the user states they want to start the migration workflow, you simply need to call the start_space_to_space_migration tool.
|
|
2366
|
-
|
|
2367
|
-
# Error Handling and Debugging
|
|
2368
|
-
|
|
2369
|
-
## Error Response Strategy:
|
|
2370
|
-
- If you encounter an error, explain what went wrong clearly
|
|
2371
|
-
- Suggest potential solutions or alternatives
|
|
2372
|
-
- Make sure to check entry existence, field requirements, and permission issues
|
|
2373
|
-
- Try different approaches immediately rather than stopping at the first error
|
|
2374
|
-
|
|
2375
|
-
## Common Issues to Check:
|
|
2376
|
-
- entry existence and permissions
|
|
2377
|
-
- Required field validation
|
|
2378
|
-
- Correct field types (array vs single reference)
|
|
2379
|
-
|
|
2380
|
-
# Response Format and Communication
|
|
2381
|
-
|
|
2382
|
-
## General Guidelines:
|
|
2383
|
-
- Keep your responses concise but thorough
|
|
2384
|
-
- Format complex data for readability using markdown
|
|
2385
|
-
- Focus on completing the requested tasks efficiently
|
|
2386
|
-
- Provide context from entries when relevant
|
|
2387
|
-
- When displaying entries, show the most important fields first
|
|
2388
|
-
|
|
2389
|
-
## Before Using Tools:
|
|
2390
|
-
Before running a tool:
|
|
2391
|
-
1. Think about what information you need to gather
|
|
2392
|
-
2. Determine the right tool and parameters to use
|
|
2393
|
-
3. Briefly communicate to the user what you're about to do in a conversational tone
|
|
2394
|
-
|
|
2395
|
-
## Problem-Solving Strategy:
|
|
2396
|
-
1. **Understand the request**: Analyze what the user is asking for and identify necessary entry types and fields
|
|
2397
|
-
2. **Resource identification**: If multiple resources are available, ALWAYS ask which resource to work with
|
|
2398
|
-
3. **Plan your approach**: Determine which tools you'll need and in which order
|
|
2399
|
-
4. **Execute with tools**: Use appropriate tools to query, create, or update entries
|
|
2400
|
-
5. **Verify results**: Check if results match what the user requested and make adjustments if needed
|
|
2401
|
-
6. **Respond clearly**: Present results in a clear, concise format
|
|
2402
|
-
|
|
2403
|
-
# Best Practices
|
|
2404
|
-
|
|
2405
|
-
## Content Management:
|
|
2406
|
-
- When creating content, follow the content type structure exactly
|
|
2407
|
-
- Always verify entry existence before attempting to modify it
|
|
2408
|
-
- Remind users that entry operations can affect live content
|
|
2409
|
-
|
|
2410
|
-
## Efficiency Tips:
|
|
2411
|
-
- Suggest appropriate entry types based on user needs
|
|
2412
|
-
- Recommend efficient ways to structure content
|
|
2413
|
-
- Explain how Contentful features like content types, entries, and references work
|
|
2414
|
-
- Help users understand the relationship between spaces, environments, and content types
|
|
2415
|
-
|
|
2416
|
-
## Bulk Actions:
|
|
2417
|
-
- If making multiple calls to the same tool, ALWAYS check and see whether that tool supports bulk operations first, and condense them into a single call if possible.
|
|
2418
|
-
|
|
2419
|
-
You have access to powerful tools that can help you work with Contentful effectively. Always start with get_initial_context, check the schema when needed, clarify resources when multiple exist, and take action to complete user requests fully.`;
|
|
2311
|
+
var CORE_INVARIANTS = `# Core operating rules
|
|
2312
|
+
|
|
2313
|
+
- **Schema first.** Before creating or finding content, inspect the environment's schema: list available types and inspect their fields. This prevents failed operations and ensures you use the right type and field names.
|
|
2314
|
+
- **Edit safely.** Before updating any item, fetch it first to get the current \`sys.version\`, then pass that version to the update call. The version is required and prevents overwriting concurrent changes.
|
|
2315
|
+
- **Bulk cap.** Bulk publish/unpublish/archive/unarchive operations accept at most 10 IDs per call by default. This cap does not apply to creating or updating items.
|
|
2316
|
+
- **Ask when ambiguous.** If multiple spaces or environments are available, ask the user which to use. Do not guess.`;
|
|
2317
|
+
var SEARCHING_GUIDANCE = `# Searching for content
|
|
2318
|
+
|
|
2319
|
+
- **Schema first.** When users ask about specific content, discover the relevant schema before searching: list the environment's available types and inspect a type's fields so you query on real field names. This prevents wasted queries. Use whichever primitives the environment exposes \u2014 classic content types and entries, or Experience Orchestration components and experiences.
|
|
2320
|
+
- **Then search.** Query using the correct type and field names. Prefer semantic search when the request is conceptual rather than an exact field match.
|
|
2321
|
+
- **Retry thoughtfully.** If a query returns no results, retry 2-3 times: relax filters, use more general terms, or check for typos in field names.
|
|
2322
|
+
- **Multi-step reference queries.** For requests that span references (e.g. "posts by Magnus"), first inspect the schema to confirm the reference field, then query for the referenced item to get its ID, then filter the primary query on that ID. If several items match, show them all and ask.`;
|
|
2323
|
+
var CONVENTIONS_GUIDANCE = `# Response and workflow conventions
|
|
2324
|
+
|
|
2325
|
+
- **Plan, then act.** Before a tool call, think about what you need, pick the right tool, and briefly tell the user what you are about to do.
|
|
2326
|
+
- **Persist.** Keep going until the request is fully resolved; do not stop at the first error. On failure, explain what went wrong and immediately try a different approach \u2014 never apologize for tool errors.
|
|
2327
|
+
- **Clarify resources.** If multiple spaces or environments exist, always ask which to use before acting.
|
|
2328
|
+
- **Format for readability.** Use markdown for complex data; show the most important fields of an entry first; keep responses concise but complete.
|
|
2329
|
+
- **Prefer bulk.** If you would call the same tool many times, check whether it supports multiple IDs and condense into one call (respecting the 10-ID cap on publish-family operations).`;
|
|
2330
|
+
var EXO_DISPOSITION = `# Tool disposition: Experience Orchestration by default
|
|
2331
|
+
|
|
2332
|
+
Experience Orchestration (ExO) tools are enabled. Use ExO primitives \u2014 Components, Experiences, Experience Templates, Experience Fragments, and Data Assemblies \u2014 for all content modeling and authoring. Do not create classic content types or entries unless the user explicitly instructs you to. If you are unsure how to model something with ExO, inspect the tool schemas and proceed with ExO.`;
|
|
2420
2333
|
|
|
2421
2334
|
// src/tools/context/getInitialContextTool.ts
|
|
2422
2335
|
var GetInitialContextToolParams = z35.object({});
|
|
2423
2336
|
function getInitialContextTool(config) {
|
|
2424
2337
|
async function tool2(_params) {
|
|
2425
|
-
const
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2338
|
+
const today = (/* @__PURE__ */ new Date()).toLocaleDateString("en-US", {
|
|
2339
|
+
weekday: "long",
|
|
2340
|
+
year: "numeric",
|
|
2341
|
+
month: "long",
|
|
2342
|
+
day: "numeric"
|
|
2343
|
+
});
|
|
2344
|
+
const sessionFacts = outdent`
|
|
2345
|
+
Current Contentful session:
|
|
2346
|
+
- Today's date: ${today}
|
|
2347
|
+
- Space ID: ${config.spaceId || "Not set"}
|
|
2348
|
+
- Environment ID: ${config.environmentId || "master"}
|
|
2349
|
+
- Organization ID: ${config.organizationId || "Not set"}`;
|
|
2350
|
+
const exoBlock = config.exoToolsRegistered ? `
|
|
2351
|
+
|
|
2352
|
+
${EXO_DISPOSITION}` : "";
|
|
2430
2353
|
const message = outdent`
|
|
2431
|
-
|
|
2354
|
+
You are an assistant integrated with Contentful through the Model Context Protocol (MCP). Always call this tool first.
|
|
2355
|
+
|
|
2356
|
+
${sessionFacts}
|
|
2357
|
+
` + exoBlock + `
|
|
2432
2358
|
|
|
2433
|
-
|
|
2359
|
+
` + outdent`
|
|
2360
|
+
${CORE_INVARIANTS}
|
|
2434
2361
|
|
|
2435
|
-
|
|
2436
|
-
${configInfo}
|
|
2437
|
-
</content>
|
|
2362
|
+
${SEARCHING_GUIDANCE}
|
|
2438
2363
|
|
|
2439
|
-
|
|
2440
|
-
|
|
2364
|
+
${CONVENTIONS_GUIDANCE}
|
|
2365
|
+
`;
|
|
2441
2366
|
contextStore.setInitialContextLoaded();
|
|
2442
2367
|
return {
|
|
2443
2368
|
content: [
|
|
@@ -5786,85 +5711,2481 @@ function createJobTools(config) {
|
|
|
5786
5711
|
};
|
|
5787
5712
|
}
|
|
5788
5713
|
|
|
5789
|
-
// src/
|
|
5790
|
-
|
|
5791
|
-
|
|
5792
|
-
|
|
5793
|
-
|
|
5794
|
-
|
|
5795
|
-
|
|
5796
|
-
|
|
5797
|
-
|
|
5798
|
-
|
|
5799
|
-
|
|
5800
|
-
|
|
5801
|
-
|
|
5802
|
-
|
|
5803
|
-
|
|
5804
|
-
|
|
5805
|
-
this.config = { ...this.config, ...updates };
|
|
5806
|
-
}
|
|
5807
|
-
/**
|
|
5808
|
-
* Get AI action tools
|
|
5809
|
-
*/
|
|
5810
|
-
getAiActionTools() {
|
|
5811
|
-
return createAiActionTools(this.config);
|
|
5812
|
-
}
|
|
5813
|
-
/**
|
|
5814
|
-
* Get asset tools
|
|
5815
|
-
*/
|
|
5816
|
-
getAssetTools() {
|
|
5817
|
-
return createAssetTools(this.config);
|
|
5818
|
-
}
|
|
5819
|
-
/**
|
|
5820
|
-
* Get content type tools
|
|
5821
|
-
*/
|
|
5822
|
-
getContentTypeTools() {
|
|
5823
|
-
return createContentTypeTools(this.config);
|
|
5714
|
+
// src/tools/exo/components/getComponent.ts
|
|
5715
|
+
import { z as z83 } from "zod";
|
|
5716
|
+
var GetComponentToolParams = BaseToolSchema.extend({
|
|
5717
|
+
componentId: z83.string().describe("The ID of the component to retrieve details for")
|
|
5718
|
+
});
|
|
5719
|
+
function getComponentTool(config) {
|
|
5720
|
+
async function tool2(args) {
|
|
5721
|
+
const contentfulClient = createToolClient(config, args);
|
|
5722
|
+
const component = await contentfulClient.component.get({
|
|
5723
|
+
spaceId: args.spaceId,
|
|
5724
|
+
environmentId: args.environmentId,
|
|
5725
|
+
componentId: args.componentId
|
|
5726
|
+
});
|
|
5727
|
+
return createSuccessResponse("Component retrieved successfully", {
|
|
5728
|
+
component
|
|
5729
|
+
});
|
|
5824
5730
|
}
|
|
5825
|
-
|
|
5826
|
-
|
|
5827
|
-
|
|
5828
|
-
|
|
5829
|
-
|
|
5731
|
+
return withErrorHandling(tool2, "Error retrieving component");
|
|
5732
|
+
}
|
|
5733
|
+
|
|
5734
|
+
// src/tools/exo/components/listComponents.ts
|
|
5735
|
+
import { z as z84 } from "zod";
|
|
5736
|
+
var ListComponentsToolParams = BaseToolSchema.extend({
|
|
5737
|
+
limit: z84.number().optional().describe("Maximum number of components to return (max 10)"),
|
|
5738
|
+
pageNext: z84.string().optional().describe("Cursor token to fetch the next page of results"),
|
|
5739
|
+
pagePrev: z84.string().optional().describe("Cursor token to fetch the previous page of results"),
|
|
5740
|
+
order: z84.string().optional().describe("Order components by this field (e.g. sys.createdAt)")
|
|
5741
|
+
});
|
|
5742
|
+
function listComponentsTool(config) {
|
|
5743
|
+
async function tool2(args) {
|
|
5744
|
+
const contentfulClient = createToolClient(config, args);
|
|
5745
|
+
const cursorParam = args.pageNext ? { pageNext: args.pageNext } : args.pagePrev ? { pagePrev: args.pagePrev } : {};
|
|
5746
|
+
const components = await contentfulClient.component.getMany({
|
|
5747
|
+
spaceId: args.spaceId,
|
|
5748
|
+
environmentId: args.environmentId,
|
|
5749
|
+
query: {
|
|
5750
|
+
limit: Math.min(args.limit || 10, 10),
|
|
5751
|
+
...args.order && { order: args.order },
|
|
5752
|
+
...cursorParam
|
|
5753
|
+
}
|
|
5754
|
+
});
|
|
5755
|
+
const summarized = summarizeData(components, {
|
|
5756
|
+
maxItems: 10,
|
|
5757
|
+
remainingMessage: "To see more components, ask me to retrieve the next page using the pageNext cursor."
|
|
5758
|
+
});
|
|
5759
|
+
return createSuccessResponse("Components retrieved successfully", {
|
|
5760
|
+
components: summarized,
|
|
5761
|
+
total: components.total,
|
|
5762
|
+
limit: components.limit,
|
|
5763
|
+
pages: components.pages
|
|
5764
|
+
});
|
|
5830
5765
|
}
|
|
5831
|
-
|
|
5832
|
-
|
|
5833
|
-
|
|
5834
|
-
|
|
5835
|
-
|
|
5766
|
+
return withErrorHandling(tool2, "Error listing components");
|
|
5767
|
+
}
|
|
5768
|
+
|
|
5769
|
+
// src/tools/exo/components/createComponent.ts
|
|
5770
|
+
import { z as z86 } from "zod";
|
|
5771
|
+
|
|
5772
|
+
// src/types/exoSchemas.ts
|
|
5773
|
+
import { z as z85 } from "zod";
|
|
5774
|
+
var URN_EXAMPLES = {
|
|
5775
|
+
"Contentful:Component": "crn:contentful:::experience:spaces/{spaceId}/environments/{envId}/components/{id}",
|
|
5776
|
+
"Contentful:ExperienceFragment": "crn:contentful:::experience:spaces/{spaceId}/environments/{envId}/experienceFragments/{id}",
|
|
5777
|
+
"Contentful:ExperienceTemplate": "crn:contentful:::experience:spaces/{spaceId}/environments/{envId}/experienceTemplates/{id}",
|
|
5778
|
+
"Contentful:DataAssembly": "crn:contentful:::experience:spaces/{spaceId}/environments/{envId}/dataAssemblies/{id}"
|
|
5779
|
+
};
|
|
5780
|
+
var resourceLinkSchema2 = (linkType) => {
|
|
5781
|
+
const example = URN_EXAMPLES[linkType];
|
|
5782
|
+
const urnDesc = example ? `URN of the linked resource (e.g. "${example}")` : "URN of the linked resource";
|
|
5783
|
+
return z85.object({
|
|
5784
|
+
sys: z85.object({
|
|
5785
|
+
type: z85.literal("ResourceLink"),
|
|
5786
|
+
linkType: z85.literal(linkType),
|
|
5787
|
+
urn: z85.string().describe(urnDesc)
|
|
5788
|
+
})
|
|
5789
|
+
});
|
|
5790
|
+
};
|
|
5791
|
+
var linkSchema2 = (linkType) => z85.object({
|
|
5792
|
+
sys: z85.object({
|
|
5793
|
+
type: z85.literal("Link"),
|
|
5794
|
+
linkType: z85.literal(linkType),
|
|
5795
|
+
id: z85.string()
|
|
5796
|
+
})
|
|
5797
|
+
});
|
|
5798
|
+
var ComponentResourceLinkSchema = resourceLinkSchema2(
|
|
5799
|
+
"Contentful:Component"
|
|
5800
|
+
);
|
|
5801
|
+
var ExperienceFragmentResourceLinkSchema = resourceLinkSchema2(
|
|
5802
|
+
"Contentful:ExperienceFragment"
|
|
5803
|
+
);
|
|
5804
|
+
var ExperienceTemplateResourceLinkSchema = resourceLinkSchema2(
|
|
5805
|
+
"Contentful:ExperienceTemplate"
|
|
5806
|
+
);
|
|
5807
|
+
var ViewportSchema = z85.object({
|
|
5808
|
+
id: z85.string().describe("Viewport identifier"),
|
|
5809
|
+
query: z85.string().describe("CSS media query string"),
|
|
5810
|
+
displayName: z85.string().describe("Human-readable viewport name"),
|
|
5811
|
+
previewSize: z85.string().describe('Preview size (e.g. "1024px")')
|
|
5812
|
+
});
|
|
5813
|
+
var DataTypeDefinitionSchema = z85.lazy(
|
|
5814
|
+
() => z85.discriminatedUnion("type", [
|
|
5815
|
+
z85.object({
|
|
5816
|
+
type: z85.enum(["String", "Number", "Integer", "Boolean"]),
|
|
5817
|
+
name: z85.string().optional(),
|
|
5818
|
+
required: z85.boolean().optional()
|
|
5819
|
+
}),
|
|
5820
|
+
z85.object({
|
|
5821
|
+
type: z85.literal("RichText"),
|
|
5822
|
+
name: z85.string().optional(),
|
|
5823
|
+
required: z85.boolean().optional()
|
|
5824
|
+
}),
|
|
5825
|
+
z85.object({
|
|
5826
|
+
type: z85.literal("Array"),
|
|
5827
|
+
name: z85.string().optional(),
|
|
5828
|
+
required: z85.boolean().optional(),
|
|
5829
|
+
items: DataTypeDefinitionSchema
|
|
5830
|
+
}),
|
|
5831
|
+
z85.object({
|
|
5832
|
+
type: z85.literal("Record"),
|
|
5833
|
+
name: z85.string().optional(),
|
|
5834
|
+
required: z85.boolean().optional(),
|
|
5835
|
+
fields: z85.record(z85.string(), DataTypeDefinitionSchema)
|
|
5836
|
+
}),
|
|
5837
|
+
z85.object({
|
|
5838
|
+
type: z85.literal("TypeRef"),
|
|
5839
|
+
name: z85.string().optional(),
|
|
5840
|
+
required: z85.boolean().optional(),
|
|
5841
|
+
ref: z85.object({
|
|
5842
|
+
sys: z85.object({
|
|
5843
|
+
type: z85.literal("ResourceLink"),
|
|
5844
|
+
linkType: z85.string(),
|
|
5845
|
+
urn: z85.string()
|
|
5846
|
+
})
|
|
5847
|
+
})
|
|
5848
|
+
}),
|
|
5849
|
+
z85.object({
|
|
5850
|
+
type: z85.literal("Literal"),
|
|
5851
|
+
name: z85.string().optional(),
|
|
5852
|
+
required: z85.boolean().optional(),
|
|
5853
|
+
value: z85.custom().describe("JSON literal value"),
|
|
5854
|
+
valueType: DataTypeDefinitionSchema
|
|
5855
|
+
}),
|
|
5856
|
+
z85.object({
|
|
5857
|
+
type: z85.literal("DiscriminatedUnion"),
|
|
5858
|
+
name: z85.string().optional(),
|
|
5859
|
+
required: z85.boolean().optional(),
|
|
5860
|
+
discriminator: z85.string(),
|
|
5861
|
+
members: z85.array(DataTypeDefinitionSchema)
|
|
5862
|
+
})
|
|
5863
|
+
])
|
|
5864
|
+
);
|
|
5865
|
+
var ContentPropertySchema = z85.intersection(
|
|
5866
|
+
DataTypeDefinitionSchema,
|
|
5867
|
+
z85.object({
|
|
5868
|
+
id: z85.string().describe("Content property identifier"),
|
|
5869
|
+
name: z85.string().describe("Human-readable name"),
|
|
5870
|
+
required: z85.boolean().describe("Whether the property is required"),
|
|
5871
|
+
defaultValue: z85.unknown().optional().describe("Default value")
|
|
5872
|
+
})
|
|
5873
|
+
);
|
|
5874
|
+
var DTCG_DESIGN_PROPERTY_TYPES = [
|
|
5875
|
+
"DTCG.Color",
|
|
5876
|
+
"DTCG.Dimension",
|
|
5877
|
+
"DTCG.FontFamily",
|
|
5878
|
+
"DTCG.FontWeight",
|
|
5879
|
+
"DTCG.Duration",
|
|
5880
|
+
"DTCG.CubicBezier",
|
|
5881
|
+
"DTCG.Number",
|
|
5882
|
+
"DTCG.StrokeStyle",
|
|
5883
|
+
"DTCG.Border",
|
|
5884
|
+
"DTCG.Transition",
|
|
5885
|
+
"DTCG.Shadow",
|
|
5886
|
+
"DTCG.Gradient",
|
|
5887
|
+
"DTCG.Typography"
|
|
5888
|
+
];
|
|
5889
|
+
var DesignPropertyCommonFieldsSchema = z85.object({
|
|
5890
|
+
id: z85.string().describe("Design property identifier"),
|
|
5891
|
+
name: z85.string().describe("Human-readable name"),
|
|
5892
|
+
description: z85.string().optional().describe("Optional description")
|
|
5893
|
+
});
|
|
5894
|
+
var StringDesignPropertySchema = DesignPropertyCommonFieldsSchema.extend({
|
|
5895
|
+
type: z85.literal("String"),
|
|
5896
|
+
fallbackValue: z85.object({
|
|
5897
|
+
type: z85.literal("ManualDesignValue"),
|
|
5898
|
+
value: z85.string()
|
|
5899
|
+
}).optional().describe("Manual fallback value for this design property"),
|
|
5900
|
+
validations: z85.array(
|
|
5901
|
+
z85.object({
|
|
5902
|
+
regexp: z85.object({
|
|
5903
|
+
pattern: z85.string().describe("Regular expression pattern")
|
|
5904
|
+
})
|
|
5905
|
+
})
|
|
5906
|
+
).optional().describe("Regexp validations constraining allowed string values")
|
|
5907
|
+
});
|
|
5908
|
+
var BooleanDesignPropertySchema = DesignPropertyCommonFieldsSchema.extend({
|
|
5909
|
+
type: z85.literal("Boolean"),
|
|
5910
|
+
fallbackValue: z85.object({
|
|
5911
|
+
type: z85.literal("ManualDesignValue"),
|
|
5912
|
+
value: z85.boolean()
|
|
5913
|
+
}).optional().describe("Manual fallback value for this design property")
|
|
5914
|
+
});
|
|
5915
|
+
var DesignTokenValueSchema = z85.object({
|
|
5916
|
+
type: z85.literal("DesignToken"),
|
|
5917
|
+
value: z85.string().min(1).describe("Design token reference (non-empty)")
|
|
5918
|
+
});
|
|
5919
|
+
var TokenBackedDesignPropertySchema = DesignPropertyCommonFieldsSchema.extend(
|
|
5920
|
+
{
|
|
5921
|
+
type: z85.enum(DTCG_DESIGN_PROPERTY_TYPES),
|
|
5922
|
+
fallbackValue: DesignTokenValueSchema.optional().describe(
|
|
5923
|
+
"Design-token-backed fallback value for this design property"
|
|
5924
|
+
),
|
|
5925
|
+
allowedResources: z85.array(
|
|
5926
|
+
z85.object({
|
|
5927
|
+
type: z85.literal("DesignToken"),
|
|
5928
|
+
value: z85.string(),
|
|
5929
|
+
name: z85.string().optional()
|
|
5930
|
+
})
|
|
5931
|
+
).optional().describe("Allowed design token resources")
|
|
5836
5932
|
}
|
|
5837
|
-
|
|
5838
|
-
|
|
5839
|
-
|
|
5840
|
-
|
|
5841
|
-
|
|
5933
|
+
);
|
|
5934
|
+
var DesignPropertySchema = z85.union([
|
|
5935
|
+
StringDesignPropertySchema,
|
|
5936
|
+
BooleanDesignPropertySchema,
|
|
5937
|
+
TokenBackedDesignPropertySchema
|
|
5938
|
+
]);
|
|
5939
|
+
var ManualDesignValueSchema = z85.object({
|
|
5940
|
+
type: z85.literal("ManualDesignValue"),
|
|
5941
|
+
value: z85.union([z85.string(), z85.number(), z85.boolean()])
|
|
5942
|
+
});
|
|
5943
|
+
var DesignPropertyValueSchema = z85.union([
|
|
5944
|
+
ManualDesignValueSchema,
|
|
5945
|
+
DesignTokenValueSchema
|
|
5946
|
+
]);
|
|
5947
|
+
var DesignPropertyPointerValueSchema = z85.custom(
|
|
5948
|
+
(val) => typeof val === "string" && /^\$designProperties\//.test(val),
|
|
5949
|
+
{ message: 'Must be a "$designProperties/..." pointer' }
|
|
5950
|
+
);
|
|
5951
|
+
var DimensionedDesignPropertyValueSchema = z85.record(
|
|
5952
|
+
z85.string(),
|
|
5953
|
+
DesignPropertyValueSchema
|
|
5954
|
+
);
|
|
5955
|
+
var ComponentTreeDesignPropertyValueSchema = z85.union([
|
|
5956
|
+
DesignPropertyValueSchema,
|
|
5957
|
+
DesignPropertyPointerValueSchema,
|
|
5958
|
+
DimensionedDesignPropertyValueSchema
|
|
5959
|
+
]);
|
|
5960
|
+
var COMPONENT_TYPE_ALLOWED_RESOURCE_SOURCE = "crn:contentful:::experience:spaces/$self/environments/$self";
|
|
5961
|
+
var SlotDefinitionSchema = z85.object({
|
|
5962
|
+
id: z85.string().describe("Slot identifier"),
|
|
5963
|
+
name: z85.string().describe("Human-readable name"),
|
|
5964
|
+
required: z85.boolean().describe("Whether the slot must be filled"),
|
|
5965
|
+
validations: z85.array(
|
|
5966
|
+
z85.object({
|
|
5967
|
+
size: z85.object({
|
|
5968
|
+
min: z85.number().optional(),
|
|
5969
|
+
max: z85.number().optional()
|
|
5970
|
+
}).optional()
|
|
5971
|
+
})
|
|
5972
|
+
).describe("Slot cardinality validations"),
|
|
5973
|
+
allowedResources: z85.array(
|
|
5974
|
+
z85.object({
|
|
5975
|
+
type: z85.literal("Contentful:Component"),
|
|
5976
|
+
source: z85.literal(COMPONENT_TYPE_ALLOWED_RESOURCE_SOURCE),
|
|
5977
|
+
allowedTypes: z85.array(z85.string()).describe("IDs of components allowed in this slot")
|
|
5978
|
+
})
|
|
5979
|
+
).optional().describe("Constrains which components may be placed in this slot")
|
|
5980
|
+
});
|
|
5981
|
+
var ExperienceFragmentNodeSchema = z85.object({
|
|
5982
|
+
id: z85.string().describe("Node identifier"),
|
|
5983
|
+
name: z85.string().optional().describe("Optional display name"),
|
|
5984
|
+
nodeType: z85.literal("ExperienceFragment").describe('Must be "ExperienceFragment"'),
|
|
5985
|
+
experienceFragment: ExperienceFragmentResourceLinkSchema.describe(
|
|
5986
|
+
"Resource link to the referenced experience fragment"
|
|
5987
|
+
)
|
|
5988
|
+
});
|
|
5989
|
+
var SlotNodeSchema = z85.object({
|
|
5990
|
+
id: z85.string().describe("Node identifier"),
|
|
5991
|
+
nodeType: z85.literal("Slot").describe('Must be "Slot"'),
|
|
5992
|
+
slotId: z85.string().describe("ID of the slot definition to render")
|
|
5993
|
+
});
|
|
5994
|
+
var TreeNodeSchema = z85.lazy(
|
|
5995
|
+
() => z85.union([ComponentNodeSchema, ExperienceFragmentNodeSchema, SlotNodeSchema])
|
|
5996
|
+
);
|
|
5997
|
+
var ComponentNodeSchema = z85.lazy(
|
|
5998
|
+
() => z85.object({
|
|
5999
|
+
id: z85.string().describe("Node identifier"),
|
|
6000
|
+
name: z85.string().optional().describe("Optional display name"),
|
|
6001
|
+
nodeType: z85.literal("Component").describe('Must be "Component"'),
|
|
6002
|
+
component: ComponentResourceLinkSchema.describe(
|
|
6003
|
+
"Resource link to the component to render"
|
|
6004
|
+
),
|
|
6005
|
+
contentProperties: z85.union([
|
|
6006
|
+
z85.record(z85.string(), z85.unknown()),
|
|
6007
|
+
z85.string().describe('"$contentProperties/..." pointer')
|
|
6008
|
+
]).describe(
|
|
6009
|
+
'Content property bindings \u2014 values or "$contentProperties/..." pointers'
|
|
6010
|
+
),
|
|
6011
|
+
designProperties: z85.record(z85.string(), ComponentTreeDesignPropertyValueSchema).describe(
|
|
6012
|
+
'Design property values \u2014 ManualDesignValue, DesignTokenValue, or "$designProperties/..." pointers'
|
|
6013
|
+
),
|
|
6014
|
+
slots: z85.record(z85.string(), z85.array(TreeNodeSchema)).describe("Child tree nodes keyed by slot ID")
|
|
6015
|
+
})
|
|
6016
|
+
);
|
|
6017
|
+
var TagLinkSchema = linkSchema2("Tag");
|
|
6018
|
+
var ConceptLinkSchema = linkSchema2("TaxonomyConcept");
|
|
6019
|
+
var ExoMetadataSchema = z85.object({
|
|
6020
|
+
tags: z85.array(TagLinkSchema).optional().describe("Tags attached to this entity"),
|
|
6021
|
+
concepts: z85.array(ConceptLinkSchema).optional().describe("Taxonomy concepts attached to this entity")
|
|
6022
|
+
});
|
|
6023
|
+
var ExperienceMetadataSchema = ExoMetadataSchema.extend({
|
|
6024
|
+
name: z85.string().optional().describe("Variant label for this metadata entry")
|
|
6025
|
+
});
|
|
6026
|
+
var DataAssemblyResourceLinkSchema = resourceLinkSchema2(
|
|
6027
|
+
"Contentful:DataAssembly"
|
|
6028
|
+
);
|
|
6029
|
+
var ExperienceContentBindingsSchema = z85.object({
|
|
6030
|
+
sys: DataAssemblyResourceLinkSchema.shape.sys,
|
|
6031
|
+
parameters: z85.record(
|
|
6032
|
+
z85.string(),
|
|
6033
|
+
z85.object({
|
|
6034
|
+
sys: z85.object({
|
|
6035
|
+
type: z85.literal("ResourceLink"),
|
|
6036
|
+
linkType: z85.string(),
|
|
6037
|
+
urn: z85.string()
|
|
6038
|
+
})
|
|
6039
|
+
})
|
|
6040
|
+
).describe("Parameter bindings keyed by parameter ID")
|
|
6041
|
+
});
|
|
6042
|
+
var InlineExperienceFragmentNodeSchema = z85.lazy(
|
|
6043
|
+
() => z85.object({
|
|
6044
|
+
id: z85.string().describe("Node identifier"),
|
|
6045
|
+
nodeType: z85.literal("InlineExperienceFragment").describe('Must be "InlineExperienceFragment"'),
|
|
6046
|
+
component: ComponentResourceLinkSchema.describe(
|
|
6047
|
+
"Resource link to the component this inline experience fragment renders"
|
|
6048
|
+
),
|
|
6049
|
+
designProperties: z85.record(z85.string(), DimensionedDesignPropertyValueSchema).describe("Design property values for this inline experience fragment"),
|
|
6050
|
+
contentBindings: ExperienceContentBindingsSchema.optional().describe(
|
|
6051
|
+
"Optional content bindings linking this inline experience fragment to a data assembly"
|
|
6052
|
+
),
|
|
6053
|
+
slots: z85.record(z85.string(), z85.array(ExperienceSlotNodeSchema)).optional().describe("Child slot contents keyed by slot ID")
|
|
6054
|
+
})
|
|
6055
|
+
);
|
|
6056
|
+
var ExperienceSlotNodeSchema = z85.lazy(
|
|
6057
|
+
() => z85.union([ExperienceFragmentNodeSchema, InlineExperienceFragmentNodeSchema])
|
|
6058
|
+
);
|
|
6059
|
+
|
|
6060
|
+
// src/tools/exo/components/createComponent.ts
|
|
6061
|
+
var CreateComponentToolParams = BaseToolSchema.extend({
|
|
6062
|
+
name: z86.string().describe("The name of the component"),
|
|
6063
|
+
description: z86.string().describe("Description of the component"),
|
|
6064
|
+
viewports: z86.array(ViewportSchema).describe("Viewport definitions for the component (may be empty)"),
|
|
6065
|
+
contentProperties: z86.array(ContentPropertySchema).describe("Content property definitions (may be empty)"),
|
|
6066
|
+
designProperties: z86.array(DesignPropertySchema).describe("Design property definitions (may be empty)"),
|
|
6067
|
+
componentTree: z86.array(TreeNodeSchema).optional().describe("Optional component tree node definitions"),
|
|
6068
|
+
slots: z86.array(SlotDefinitionSchema).optional().describe("Optional slot definitions"),
|
|
6069
|
+
metadata: ExoMetadataSchema.optional().describe(
|
|
6070
|
+
"Optional ExO metadata (tags, concepts)"
|
|
6071
|
+
)
|
|
6072
|
+
});
|
|
6073
|
+
function createComponentTool(config) {
|
|
6074
|
+
async function tool2(args) {
|
|
6075
|
+
assertEnvironmentNotProtected(
|
|
6076
|
+
args.environmentId,
|
|
6077
|
+
config.protectedEnvironments
|
|
6078
|
+
);
|
|
6079
|
+
const contentfulClient = createToolClient(config, args);
|
|
6080
|
+
const component = await contentfulClient.component.create(
|
|
6081
|
+
{ spaceId: args.spaceId, environmentId: args.environmentId },
|
|
6082
|
+
{
|
|
6083
|
+
name: args.name,
|
|
6084
|
+
description: args.description,
|
|
6085
|
+
viewports: args.viewports,
|
|
6086
|
+
contentProperties: args.contentProperties,
|
|
6087
|
+
designProperties: args.designProperties,
|
|
6088
|
+
...args.componentTree && { componentTree: args.componentTree },
|
|
6089
|
+
...args.slots && { slots: args.slots },
|
|
6090
|
+
...args.metadata && { metadata: args.metadata }
|
|
6091
|
+
}
|
|
6092
|
+
);
|
|
6093
|
+
return createSuccessResponse("Component created successfully", {
|
|
6094
|
+
component
|
|
6095
|
+
});
|
|
5842
6096
|
}
|
|
5843
|
-
|
|
5844
|
-
|
|
5845
|
-
|
|
5846
|
-
|
|
5847
|
-
|
|
6097
|
+
return withErrorHandling(tool2, "Error creating component");
|
|
6098
|
+
}
|
|
6099
|
+
|
|
6100
|
+
// src/tools/exo/components/upsertComponent.ts
|
|
6101
|
+
import { z as z87 } from "zod";
|
|
6102
|
+
var UpsertComponentToolParams = BaseToolSchema.extend({
|
|
6103
|
+
componentId: z87.string().describe("The ID of the component to update"),
|
|
6104
|
+
version: z87.number().describe(
|
|
6105
|
+
"REQUIRED. The component's sys.version as returned by get_component. You must call get_component first to read the current state and version. The update is rejected if this does not match the current version, which means the component changed since you read it."
|
|
6106
|
+
),
|
|
6107
|
+
name: z87.string().optional().describe("The name of the component"),
|
|
6108
|
+
description: z87.string().optional().describe("Description of the component"),
|
|
6109
|
+
viewports: z87.array(ViewportSchema).optional().describe("Viewport definitions; replaces existing viewports if provided"),
|
|
6110
|
+
contentProperties: z87.array(ContentPropertySchema).optional().describe("Content property definitions; replaces existing if provided"),
|
|
6111
|
+
designProperties: z87.array(DesignPropertySchema).optional().describe("Design property definitions; replaces existing if provided"),
|
|
6112
|
+
componentTree: z87.array(TreeNodeSchema).optional().describe("Component tree node definitions; replaces existing if provided"),
|
|
6113
|
+
slots: z87.array(SlotDefinitionSchema).optional().describe("Slot definitions; replaces existing if provided"),
|
|
6114
|
+
metadata: ExoMetadataSchema.optional().describe(
|
|
6115
|
+
"ExO metadata (tags, concepts); replaces existing if provided"
|
|
6116
|
+
)
|
|
6117
|
+
});
|
|
6118
|
+
function upsertComponentTool(config) {
|
|
6119
|
+
async function tool2(args) {
|
|
6120
|
+
assertEnvironmentNotProtected(
|
|
6121
|
+
args.environmentId,
|
|
6122
|
+
config.protectedEnvironments
|
|
6123
|
+
);
|
|
6124
|
+
const params = {
|
|
6125
|
+
spaceId: args.spaceId,
|
|
6126
|
+
environmentId: args.environmentId,
|
|
6127
|
+
componentId: args.componentId
|
|
6128
|
+
};
|
|
6129
|
+
const contentfulClient = createToolClient(config, args);
|
|
6130
|
+
const current = await contentfulClient.component.get(params);
|
|
6131
|
+
if (args.version !== current.sys.version) {
|
|
6132
|
+
throw new Error(
|
|
6133
|
+
`Version conflict: the component has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the component with get_component and retry the update with the latest sys.version.`
|
|
6134
|
+
);
|
|
6135
|
+
}
|
|
6136
|
+
const component = await contentfulClient.component.upsert(params, {
|
|
6137
|
+
sys: {
|
|
6138
|
+
id: current.sys.id,
|
|
6139
|
+
type: "Component",
|
|
6140
|
+
version: current.sys.version
|
|
6141
|
+
},
|
|
6142
|
+
name: args.name ?? current.name,
|
|
6143
|
+
description: args.description ?? current.description,
|
|
6144
|
+
viewports: args.viewports ?? current.viewports,
|
|
6145
|
+
contentProperties: args.contentProperties ?? current.contentProperties,
|
|
6146
|
+
designProperties: args.designProperties ?? current.designProperties,
|
|
6147
|
+
...args.componentTree ?? current.componentTree ? { componentTree: args.componentTree ?? current.componentTree } : {},
|
|
6148
|
+
...args.slots ?? current.slots ? { slots: args.slots ?? current.slots } : {},
|
|
6149
|
+
...args.metadata ?? current.metadata ? { metadata: args.metadata ?? current.metadata } : {},
|
|
6150
|
+
...current.dataAssemblies ? { dataAssemblies: current.dataAssemblies } : {}
|
|
6151
|
+
});
|
|
6152
|
+
return createSuccessResponse("Component updated successfully", {
|
|
6153
|
+
component
|
|
6154
|
+
});
|
|
5848
6155
|
}
|
|
5849
|
-
|
|
5850
|
-
|
|
5851
|
-
|
|
5852
|
-
|
|
5853
|
-
|
|
6156
|
+
return withErrorHandling(tool2, "Error updating component");
|
|
6157
|
+
}
|
|
6158
|
+
|
|
6159
|
+
// src/tools/exo/components/deleteComponent.ts
|
|
6160
|
+
import { z as z88 } from "zod";
|
|
6161
|
+
var DeleteComponentToolParams = BaseToolSchema.extend({
|
|
6162
|
+
componentId: z88.string().describe("The ID of the component to delete"),
|
|
6163
|
+
confirm: z88.boolean().optional().describe(
|
|
6164
|
+
"Set to true on the second call to actually perform the deletion. Required together with confirmToken."
|
|
6165
|
+
),
|
|
6166
|
+
confirmToken: z88.string().optional().describe(
|
|
6167
|
+
"Token returned by the preview call; must be supplied with confirm: true."
|
|
6168
|
+
)
|
|
6169
|
+
});
|
|
6170
|
+
function deleteComponentTool(config) {
|
|
6171
|
+
async function tool2(args) {
|
|
6172
|
+
assertEnvironmentNotProtected(
|
|
6173
|
+
args.environmentId,
|
|
6174
|
+
config.protectedEnvironments
|
|
6175
|
+
);
|
|
6176
|
+
const params = {
|
|
6177
|
+
spaceId: args.spaceId,
|
|
6178
|
+
environmentId: args.environmentId,
|
|
6179
|
+
componentId: args.componentId
|
|
6180
|
+
};
|
|
6181
|
+
const contentfulClient = createToolClient(config, args);
|
|
6182
|
+
const component = await contentfulClient.component.get(params);
|
|
6183
|
+
const expectedToken = buildConfirmToken(
|
|
6184
|
+
"component",
|
|
6185
|
+
args.componentId,
|
|
6186
|
+
component.sys.version
|
|
6187
|
+
);
|
|
6188
|
+
if (args.confirm !== true || args.confirmToken !== expectedToken) {
|
|
6189
|
+
return createSuccessResponse(
|
|
6190
|
+
`${CONFIRMATION_MESSAGE_PREFIX} component`,
|
|
6191
|
+
buildConfirmationPreview(
|
|
6192
|
+
"component",
|
|
6193
|
+
args.componentId,
|
|
6194
|
+
{ component },
|
|
6195
|
+
expectedToken
|
|
6196
|
+
)
|
|
6197
|
+
);
|
|
6198
|
+
}
|
|
6199
|
+
await contentfulClient.component.delete(params);
|
|
6200
|
+
return createSuccessResponse("Component deleted successfully", {
|
|
6201
|
+
componentId: args.componentId
|
|
6202
|
+
});
|
|
5854
6203
|
}
|
|
5855
|
-
|
|
5856
|
-
|
|
5857
|
-
|
|
5858
|
-
|
|
5859
|
-
|
|
6204
|
+
return withErrorHandling(tool2, "Error deleting component");
|
|
6205
|
+
}
|
|
6206
|
+
|
|
6207
|
+
// src/tools/exo/components/publishComponent.ts
|
|
6208
|
+
import { z as z89 } from "zod";
|
|
6209
|
+
var PublishComponentToolParams = BaseToolSchema.extend({
|
|
6210
|
+
componentId: z89.string().describe("The ID of the component to publish"),
|
|
6211
|
+
version: z89.number().describe(
|
|
6212
|
+
"REQUIRED. The component's sys.version as returned by get_component. You must call get_component first to read the current state and version. The publish is rejected if this does not match the current version, which means the component changed since you read it."
|
|
6213
|
+
)
|
|
6214
|
+
});
|
|
6215
|
+
function publishComponentTool(config) {
|
|
6216
|
+
async function tool2(args) {
|
|
6217
|
+
assertEnvironmentNotProtected(
|
|
6218
|
+
args.environmentId,
|
|
6219
|
+
config.protectedEnvironments
|
|
6220
|
+
);
|
|
6221
|
+
const params = {
|
|
6222
|
+
spaceId: args.spaceId,
|
|
6223
|
+
environmentId: args.environmentId,
|
|
6224
|
+
componentId: args.componentId
|
|
6225
|
+
};
|
|
6226
|
+
const contentfulClient = createToolClient(config, args);
|
|
6227
|
+
const current = await contentfulClient.component.get(params);
|
|
6228
|
+
if (args.version !== current.sys.version) {
|
|
6229
|
+
throw new Error(
|
|
6230
|
+
`Version conflict: the component has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the component with get_component and retry with the latest sys.version.`
|
|
6231
|
+
);
|
|
6232
|
+
}
|
|
6233
|
+
const component = await contentfulClient.component.publish({
|
|
6234
|
+
...params,
|
|
6235
|
+
version: args.version
|
|
6236
|
+
});
|
|
6237
|
+
return createSuccessResponse("Component published successfully", {
|
|
6238
|
+
component
|
|
6239
|
+
});
|
|
5860
6240
|
}
|
|
5861
|
-
|
|
5862
|
-
|
|
5863
|
-
|
|
5864
|
-
|
|
5865
|
-
|
|
6241
|
+
return withErrorHandling(tool2, "Error publishing component");
|
|
6242
|
+
}
|
|
6243
|
+
|
|
6244
|
+
// src/tools/exo/components/unpublishComponent.ts
|
|
6245
|
+
import { z as z90 } from "zod";
|
|
6246
|
+
var UnpublishComponentToolParams = BaseToolSchema.extend({
|
|
6247
|
+
componentId: z90.string().describe("The ID of the component to unpublish"),
|
|
6248
|
+
version: z90.number().describe(
|
|
6249
|
+
"REQUIRED. The component's sys.version as returned by get_component. You must call get_component first to read the current state and version. The unpublish is rejected if this does not match the current version, which means the component changed since you read it."
|
|
6250
|
+
)
|
|
6251
|
+
});
|
|
6252
|
+
function unpublishComponentTool(config) {
|
|
6253
|
+
async function tool2(args) {
|
|
6254
|
+
assertEnvironmentNotProtected(
|
|
6255
|
+
args.environmentId,
|
|
6256
|
+
config.protectedEnvironments
|
|
6257
|
+
);
|
|
6258
|
+
const params = {
|
|
6259
|
+
spaceId: args.spaceId,
|
|
6260
|
+
environmentId: args.environmentId,
|
|
6261
|
+
componentId: args.componentId
|
|
6262
|
+
};
|
|
6263
|
+
const contentfulClient = createToolClient(config, args);
|
|
6264
|
+
const current = await contentfulClient.component.get(params);
|
|
6265
|
+
if (args.version !== current.sys.version) {
|
|
6266
|
+
throw new Error(
|
|
6267
|
+
`Version conflict: the component has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the component with get_component and retry with the latest sys.version.`
|
|
6268
|
+
);
|
|
6269
|
+
}
|
|
6270
|
+
const component = await contentfulClient.component.unpublish({
|
|
6271
|
+
...params,
|
|
6272
|
+
version: args.version
|
|
6273
|
+
});
|
|
6274
|
+
return createSuccessResponse("Component unpublished successfully", {
|
|
6275
|
+
component
|
|
6276
|
+
});
|
|
5866
6277
|
}
|
|
5867
|
-
|
|
6278
|
+
return withErrorHandling(tool2, "Error unpublishing component");
|
|
6279
|
+
}
|
|
6280
|
+
|
|
6281
|
+
// src/tools/exo/components/register.ts
|
|
6282
|
+
function createComponentTools(config) {
|
|
6283
|
+
const getComponent = getComponentTool(config);
|
|
6284
|
+
const listComponents = listComponentsTool(config);
|
|
6285
|
+
const createComponent = createComponentTool(config);
|
|
6286
|
+
const upsertComponent = upsertComponentTool(config);
|
|
6287
|
+
const deleteComponent = deleteComponentTool(config);
|
|
6288
|
+
const publishComponent = publishComponentTool(config);
|
|
6289
|
+
const unpublishComponent = unpublishComponentTool(config);
|
|
6290
|
+
return {
|
|
6291
|
+
getComponent: {
|
|
6292
|
+
title: "get_component",
|
|
6293
|
+
description: "Get details about a specific ExO component (a reusable section/pattern template defining slots, content properties, and design properties).",
|
|
6294
|
+
inputParams: GetComponentToolParams.shape,
|
|
6295
|
+
annotations: {
|
|
6296
|
+
readOnlyHint: true,
|
|
6297
|
+
destructiveHint: false,
|
|
6298
|
+
openWorldHint: false
|
|
6299
|
+
},
|
|
6300
|
+
tool: getComponent
|
|
6301
|
+
},
|
|
6302
|
+
listComponents: {
|
|
6303
|
+
title: "list_components",
|
|
6304
|
+
description: "List ExO components in a space and environment. Returns a maximum of 10 items per request; use the pageNext cursor (returned in pages.next) to paginate.",
|
|
6305
|
+
inputParams: ListComponentsToolParams.shape,
|
|
6306
|
+
annotations: {
|
|
6307
|
+
readOnlyHint: true,
|
|
6308
|
+
destructiveHint: false,
|
|
6309
|
+
openWorldHint: false
|
|
6310
|
+
},
|
|
6311
|
+
tool: listComponents
|
|
6312
|
+
},
|
|
6313
|
+
createComponent: {
|
|
6314
|
+
title: "create_component",
|
|
6315
|
+
description: "Create a new ExO component.",
|
|
6316
|
+
inputParams: CreateComponentToolParams.shape,
|
|
6317
|
+
annotations: {
|
|
6318
|
+
readOnlyHint: false,
|
|
6319
|
+
destructiveHint: false,
|
|
6320
|
+
idempotentHint: false,
|
|
6321
|
+
openWorldHint: false
|
|
6322
|
+
},
|
|
6323
|
+
tool: createComponent
|
|
6324
|
+
},
|
|
6325
|
+
upsertComponent: {
|
|
6326
|
+
title: "upsert_component",
|
|
6327
|
+
description: "Update an existing ExO component. You MUST call get_component first to read the current state, then pass the sys.version you received as the version parameter. The handler merges your updates with the existing component fields, so you only need to provide the fields you want to change. If the version is stale (the component changed since you read it), the update is rejected and you must re-fetch with get_component.",
|
|
6328
|
+
inputParams: UpsertComponentToolParams.shape,
|
|
6329
|
+
annotations: {
|
|
6330
|
+
readOnlyHint: false,
|
|
6331
|
+
destructiveHint: false,
|
|
6332
|
+
idempotentHint: false,
|
|
6333
|
+
openWorldHint: false
|
|
6334
|
+
},
|
|
6335
|
+
tool: upsertComponent
|
|
6336
|
+
},
|
|
6337
|
+
deleteComponent: {
|
|
6338
|
+
title: "delete_component",
|
|
6339
|
+
description: "Delete an ExO component. Two-phase: the first call (without confirm/confirmToken) returns a preview and a confirmToken. To complete the deletion, call again with the same componentId, confirm: true, and the confirmToken from the preview.",
|
|
6340
|
+
inputParams: DeleteComponentToolParams.shape,
|
|
6341
|
+
annotations: {
|
|
6342
|
+
readOnlyHint: false,
|
|
6343
|
+
destructiveHint: true,
|
|
6344
|
+
idempotentHint: false,
|
|
6345
|
+
openWorldHint: false
|
|
6346
|
+
},
|
|
6347
|
+
tool: deleteComponent
|
|
6348
|
+
},
|
|
6349
|
+
publishComponent: {
|
|
6350
|
+
title: "publish_component",
|
|
6351
|
+
description: "Publish an ExO component. You MUST call get_component first and pass the returned sys.version as the version parameter. If the version is stale the operation is rejected and you must re-fetch with get_component.",
|
|
6352
|
+
inputParams: PublishComponentToolParams.shape,
|
|
6353
|
+
annotations: {
|
|
6354
|
+
readOnlyHint: false,
|
|
6355
|
+
destructiveHint: true,
|
|
6356
|
+
idempotentHint: true,
|
|
6357
|
+
openWorldHint: false
|
|
6358
|
+
},
|
|
6359
|
+
tool: publishComponent
|
|
6360
|
+
},
|
|
6361
|
+
unpublishComponent: {
|
|
6362
|
+
title: "unpublish_component",
|
|
6363
|
+
description: "Unpublish an ExO component. You MUST call get_component first and pass the returned sys.version as the version parameter. If the version is stale the operation is rejected and you must re-fetch with get_component.",
|
|
6364
|
+
inputParams: UnpublishComponentToolParams.shape,
|
|
6365
|
+
annotations: {
|
|
6366
|
+
readOnlyHint: false,
|
|
6367
|
+
destructiveHint: true,
|
|
6368
|
+
idempotentHint: true,
|
|
6369
|
+
openWorldHint: false
|
|
6370
|
+
},
|
|
6371
|
+
tool: unpublishComponent
|
|
6372
|
+
}
|
|
6373
|
+
};
|
|
6374
|
+
}
|
|
6375
|
+
|
|
6376
|
+
// src/tools/exo/experience-fragments/getExperienceFragment.ts
|
|
6377
|
+
import { z as z91 } from "zod";
|
|
6378
|
+
var GetExperienceFragmentToolParams = BaseToolSchema.extend({
|
|
6379
|
+
experienceFragmentId: z91.string().describe("The ID of the experience fragment to retrieve details for")
|
|
6380
|
+
});
|
|
6381
|
+
function getExperienceFragmentTool(config) {
|
|
6382
|
+
async function tool2(args) {
|
|
6383
|
+
const contentfulClient = createToolClient(config, args);
|
|
6384
|
+
const experienceFragment = await contentfulClient.experienceFragment.get({
|
|
6385
|
+
spaceId: args.spaceId,
|
|
6386
|
+
environmentId: args.environmentId,
|
|
6387
|
+
experienceFragmentId: args.experienceFragmentId
|
|
6388
|
+
});
|
|
6389
|
+
return createSuccessResponse("Experience fragment retrieved successfully", {
|
|
6390
|
+
experienceFragment
|
|
6391
|
+
});
|
|
6392
|
+
}
|
|
6393
|
+
return withErrorHandling(tool2, "Error retrieving experience fragment");
|
|
6394
|
+
}
|
|
6395
|
+
|
|
6396
|
+
// src/tools/exo/experience-fragments/listExperienceFragments.ts
|
|
6397
|
+
import { z as z92 } from "zod";
|
|
6398
|
+
var ListExperienceFragmentsToolParams = BaseToolSchema.extend({
|
|
6399
|
+
limit: z92.number().optional().describe("Maximum number of experience fragments to return (max 10)"),
|
|
6400
|
+
pageNext: z92.string().optional().describe("Cursor token to fetch the next page of results"),
|
|
6401
|
+
pagePrev: z92.string().optional().describe("Cursor token to fetch the previous page of results"),
|
|
6402
|
+
order: z92.string().optional().describe("Order experience fragments by this field (e.g. sys.createdAt)")
|
|
6403
|
+
});
|
|
6404
|
+
function listExperienceFragmentsTool(config) {
|
|
6405
|
+
async function tool2(args) {
|
|
6406
|
+
const contentfulClient = createToolClient(config, args);
|
|
6407
|
+
const experienceFragments = await contentfulClient.experienceFragment.getMany({
|
|
6408
|
+
spaceId: args.spaceId,
|
|
6409
|
+
environmentId: args.environmentId,
|
|
6410
|
+
query: {
|
|
6411
|
+
limit: Math.min(args.limit || 10, 10),
|
|
6412
|
+
...args.pageNext && { pageNext: args.pageNext },
|
|
6413
|
+
...args.pagePrev && { pagePrev: args.pagePrev },
|
|
6414
|
+
...args.order && { order: args.order }
|
|
6415
|
+
}
|
|
6416
|
+
});
|
|
6417
|
+
const summarized = summarizeData(experienceFragments, {
|
|
6418
|
+
maxItems: 10,
|
|
6419
|
+
remainingMessage: "To see more experience fragments, ask me to retrieve the next page using the pageNext cursor."
|
|
6420
|
+
});
|
|
6421
|
+
return createSuccessResponse("ExperienceFragments retrieved successfully", {
|
|
6422
|
+
experienceFragments: summarized,
|
|
6423
|
+
total: experienceFragments.total,
|
|
6424
|
+
limit: experienceFragments.limit,
|
|
6425
|
+
pages: experienceFragments.pages
|
|
6426
|
+
});
|
|
6427
|
+
}
|
|
6428
|
+
return withErrorHandling(tool2, "Error listing experience fragments");
|
|
6429
|
+
}
|
|
6430
|
+
|
|
6431
|
+
// src/tools/exo/experience-fragments/createExperienceFragment.ts
|
|
6432
|
+
import { z as z93 } from "zod";
|
|
6433
|
+
var CreateExperienceFragmentToolParams = BaseToolSchema.extend({
|
|
6434
|
+
name: z93.string().describe("The name of the experience fragment"),
|
|
6435
|
+
description: z93.string().describe("Description of the experience fragment"),
|
|
6436
|
+
component: ComponentResourceLinkSchema.describe(
|
|
6437
|
+
"Resource link to the component this experience fragment is based on"
|
|
6438
|
+
),
|
|
6439
|
+
viewports: z93.array(ViewportSchema).describe("Viewport definitions (may be empty)"),
|
|
6440
|
+
designProperties: z93.record(z93.string(), DimensionedDesignPropertyValueSchema).describe(
|
|
6441
|
+
"Design property values keyed by property ID (may be empty object)"
|
|
6442
|
+
),
|
|
6443
|
+
contentBindings: ExperienceContentBindingsSchema.optional().describe(
|
|
6444
|
+
"Optional content bindings for the experience fragment"
|
|
6445
|
+
),
|
|
6446
|
+
slots: z93.record(z93.string(), z93.array(ExperienceSlotNodeSchema)).optional().describe("Optional slot node definitions keyed by slot ID"),
|
|
6447
|
+
metadata: ExperienceMetadataSchema.optional().describe(
|
|
6448
|
+
"Optional ExO metadata (tags, concepts)"
|
|
6449
|
+
)
|
|
6450
|
+
});
|
|
6451
|
+
function createExperienceFragmentTool(config) {
|
|
6452
|
+
async function tool2(args) {
|
|
6453
|
+
assertEnvironmentNotProtected(
|
|
6454
|
+
args.environmentId,
|
|
6455
|
+
config.protectedEnvironments
|
|
6456
|
+
);
|
|
6457
|
+
const contentfulClient = createToolClient(config, args);
|
|
6458
|
+
const experienceFragment = await contentfulClient.experienceFragment.create(
|
|
6459
|
+
{ spaceId: args.spaceId, environmentId: args.environmentId },
|
|
6460
|
+
{
|
|
6461
|
+
name: args.name,
|
|
6462
|
+
description: args.description,
|
|
6463
|
+
component: args.component,
|
|
6464
|
+
viewports: args.viewports,
|
|
6465
|
+
designProperties: args.designProperties,
|
|
6466
|
+
...args.contentBindings && { contentBindings: args.contentBindings },
|
|
6467
|
+
...args.slots && { slots: args.slots },
|
|
6468
|
+
...args.metadata && { metadata: args.metadata }
|
|
6469
|
+
}
|
|
6470
|
+
);
|
|
6471
|
+
return createSuccessResponse("Experience fragment created successfully", {
|
|
6472
|
+
experienceFragment
|
|
6473
|
+
});
|
|
6474
|
+
}
|
|
6475
|
+
return withErrorHandling(tool2, "Error creating experience fragment");
|
|
6476
|
+
}
|
|
6477
|
+
|
|
6478
|
+
// src/tools/exo/experience-fragments/updateExperienceFragment.ts
|
|
6479
|
+
import { z as z94 } from "zod";
|
|
6480
|
+
var UpdateExperienceFragmentToolParams = BaseToolSchema.extend({
|
|
6481
|
+
experienceFragmentId: z94.string().describe("The ID of the experience fragment to update"),
|
|
6482
|
+
version: z94.number().describe(
|
|
6483
|
+
"REQUIRED. The experience fragment's sys.version as returned by get_experience_fragment. You must call get_experience_fragment first to read the current state and version. The update is rejected if this does not match the current version, which means the experience fragment changed since you read it."
|
|
6484
|
+
),
|
|
6485
|
+
name: z94.string().optional().describe("The name of the experience fragment"),
|
|
6486
|
+
description: z94.string().optional().describe("Description of the experience fragment"),
|
|
6487
|
+
viewports: z94.array(ViewportSchema).optional().describe("Viewport definitions; replaces existing viewports if provided"),
|
|
6488
|
+
designProperties: z94.record(z94.string(), DimensionedDesignPropertyValueSchema).optional().describe("Design property values; replaces existing if provided"),
|
|
6489
|
+
contentBindings: ExperienceContentBindingsSchema.optional().describe(
|
|
6490
|
+
"Content bindings; replaces existing if provided"
|
|
6491
|
+
),
|
|
6492
|
+
slots: z94.record(z94.string(), z94.array(ExperienceSlotNodeSchema)).optional().describe("Slot node definitions; replaces existing if provided"),
|
|
6493
|
+
metadata: ExperienceMetadataSchema.optional().describe(
|
|
6494
|
+
"ExO metadata (tags, concepts); replaces existing if provided"
|
|
6495
|
+
)
|
|
6496
|
+
});
|
|
6497
|
+
function updateExperienceFragmentTool(config) {
|
|
6498
|
+
async function tool2(args) {
|
|
6499
|
+
assertEnvironmentNotProtected(
|
|
6500
|
+
args.environmentId,
|
|
6501
|
+
config.protectedEnvironments
|
|
6502
|
+
);
|
|
6503
|
+
const params = {
|
|
6504
|
+
spaceId: args.spaceId,
|
|
6505
|
+
environmentId: args.environmentId,
|
|
6506
|
+
experienceFragmentId: args.experienceFragmentId
|
|
6507
|
+
};
|
|
6508
|
+
const contentfulClient = createToolClient(config, args);
|
|
6509
|
+
const current = await contentfulClient.experienceFragment.get(params);
|
|
6510
|
+
if (args.version !== current.sys.version) {
|
|
6511
|
+
throw new Error(
|
|
6512
|
+
`Version conflict: the experience fragment has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the experience fragment with get_experience_fragment and retry the update with the latest sys.version.`
|
|
6513
|
+
);
|
|
6514
|
+
}
|
|
6515
|
+
const experienceFragment = await contentfulClient.experienceFragment.upsert(
|
|
6516
|
+
params,
|
|
6517
|
+
{
|
|
6518
|
+
sys: {
|
|
6519
|
+
id: current.sys.id,
|
|
6520
|
+
type: "ExperienceFragment",
|
|
6521
|
+
version: current.sys.version
|
|
6522
|
+
},
|
|
6523
|
+
name: args.name ?? current.name,
|
|
6524
|
+
description: args.description ?? current.description,
|
|
6525
|
+
viewports: args.viewports ?? current.viewports,
|
|
6526
|
+
designProperties: args.designProperties ?? current.designProperties,
|
|
6527
|
+
...args.contentBindings ?? current.contentBindings ? { contentBindings: args.contentBindings ?? current.contentBindings } : {},
|
|
6528
|
+
...args.slots ?? current.slots ? { slots: args.slots ?? current.slots } : {},
|
|
6529
|
+
...args.metadata ?? current.metadata ? { metadata: args.metadata ?? current.metadata } : {}
|
|
6530
|
+
}
|
|
6531
|
+
);
|
|
6532
|
+
return createSuccessResponse("Experience fragment updated successfully", {
|
|
6533
|
+
experienceFragment
|
|
6534
|
+
});
|
|
6535
|
+
}
|
|
6536
|
+
return withErrorHandling(tool2, "Error updating experience fragment");
|
|
6537
|
+
}
|
|
6538
|
+
|
|
6539
|
+
// src/tools/exo/experience-fragments/deleteExperienceFragment.ts
|
|
6540
|
+
import { z as z95 } from "zod";
|
|
6541
|
+
var DeleteExperienceFragmentToolParams = BaseToolSchema.extend({
|
|
6542
|
+
experienceFragmentId: z95.string().describe("The ID of the experience fragment to delete"),
|
|
6543
|
+
confirm: z95.boolean().optional().describe(
|
|
6544
|
+
"Set to true on the second call to actually perform the deletion. Required together with confirmToken."
|
|
6545
|
+
),
|
|
6546
|
+
confirmToken: z95.string().optional().describe(
|
|
6547
|
+
"Token returned by the preview call; must be supplied with confirm: true."
|
|
6548
|
+
)
|
|
6549
|
+
});
|
|
6550
|
+
function deleteExperienceFragmentTool(config) {
|
|
6551
|
+
async function tool2(args) {
|
|
6552
|
+
assertEnvironmentNotProtected(
|
|
6553
|
+
args.environmentId,
|
|
6554
|
+
config.protectedEnvironments
|
|
6555
|
+
);
|
|
6556
|
+
const params = {
|
|
6557
|
+
spaceId: args.spaceId,
|
|
6558
|
+
environmentId: args.environmentId,
|
|
6559
|
+
experienceFragmentId: args.experienceFragmentId
|
|
6560
|
+
};
|
|
6561
|
+
const contentfulClient = createToolClient(config, args);
|
|
6562
|
+
const experienceFragment = await contentfulClient.experienceFragment.get(params);
|
|
6563
|
+
const expectedToken = buildConfirmToken(
|
|
6564
|
+
"experienceFragment",
|
|
6565
|
+
args.experienceFragmentId,
|
|
6566
|
+
experienceFragment.sys.version
|
|
6567
|
+
);
|
|
6568
|
+
if (args.confirm !== true || args.confirmToken !== expectedToken) {
|
|
6569
|
+
return createSuccessResponse(
|
|
6570
|
+
`${CONFIRMATION_MESSAGE_PREFIX} experience fragment`,
|
|
6571
|
+
buildConfirmationPreview(
|
|
6572
|
+
"experienceFragment",
|
|
6573
|
+
args.experienceFragmentId,
|
|
6574
|
+
{ experienceFragment },
|
|
6575
|
+
expectedToken
|
|
6576
|
+
)
|
|
6577
|
+
);
|
|
6578
|
+
}
|
|
6579
|
+
await contentfulClient.experienceFragment.delete(params);
|
|
6580
|
+
return createSuccessResponse("Experience fragment deleted successfully", {
|
|
6581
|
+
experienceFragmentId: args.experienceFragmentId
|
|
6582
|
+
});
|
|
6583
|
+
}
|
|
6584
|
+
return withErrorHandling(tool2, "Error deleting experience fragment");
|
|
6585
|
+
}
|
|
6586
|
+
|
|
6587
|
+
// src/tools/exo/experience-fragments/publishExperienceFragment.ts
|
|
6588
|
+
import { z as z96 } from "zod";
|
|
6589
|
+
var PublishExperienceFragmentToolParams = BaseToolSchema.extend({
|
|
6590
|
+
experienceFragmentId: z96.string().describe("The ID of the experience fragment to publish"),
|
|
6591
|
+
version: z96.number().describe(
|
|
6592
|
+
"REQUIRED. The experience fragment's sys.version as returned by get_experience_fragment. You must call get_experience_fragment first to read the current state and version. The publish is rejected if this does not match the current version, which means the experience fragment changed since you read it."
|
|
6593
|
+
)
|
|
6594
|
+
});
|
|
6595
|
+
function publishExperienceFragmentTool(config) {
|
|
6596
|
+
async function tool2(args) {
|
|
6597
|
+
assertEnvironmentNotProtected(
|
|
6598
|
+
args.environmentId,
|
|
6599
|
+
config.protectedEnvironments
|
|
6600
|
+
);
|
|
6601
|
+
const params = {
|
|
6602
|
+
spaceId: args.spaceId,
|
|
6603
|
+
environmentId: args.environmentId,
|
|
6604
|
+
experienceFragmentId: args.experienceFragmentId
|
|
6605
|
+
};
|
|
6606
|
+
const contentfulClient = createToolClient(config, args);
|
|
6607
|
+
const current = await contentfulClient.experienceFragment.get(params);
|
|
6608
|
+
if (args.version !== current.sys.version) {
|
|
6609
|
+
throw new Error(
|
|
6610
|
+
`Version conflict: the experience fragment has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the experience fragment with get_experience_fragment and retry with the latest sys.version.`
|
|
6611
|
+
);
|
|
6612
|
+
}
|
|
6613
|
+
const experienceFragment = await contentfulClient.experienceFragment.publish({
|
|
6614
|
+
...params,
|
|
6615
|
+
version: args.version
|
|
6616
|
+
});
|
|
6617
|
+
return createSuccessResponse("Experience fragment published successfully", {
|
|
6618
|
+
experienceFragment
|
|
6619
|
+
});
|
|
6620
|
+
}
|
|
6621
|
+
return withErrorHandling(tool2, "Error publishing experience fragment");
|
|
6622
|
+
}
|
|
6623
|
+
|
|
6624
|
+
// src/tools/exo/experience-fragments/unpublishExperienceFragment.ts
|
|
6625
|
+
import { z as z97 } from "zod";
|
|
6626
|
+
var UnpublishExperienceFragmentToolParams = BaseToolSchema.extend({
|
|
6627
|
+
experienceFragmentId: z97.string().describe("The ID of the experience fragment to unpublish"),
|
|
6628
|
+
version: z97.number().describe(
|
|
6629
|
+
"REQUIRED. The experience fragment's sys.version as returned by get_experience_fragment. You must call get_experience_fragment first to read the current state and version. The unpublish is rejected if this does not match the current version, which means the experience fragment changed since you read it."
|
|
6630
|
+
)
|
|
6631
|
+
});
|
|
6632
|
+
function unpublishExperienceFragmentTool(config) {
|
|
6633
|
+
async function tool2(args) {
|
|
6634
|
+
assertEnvironmentNotProtected(
|
|
6635
|
+
args.environmentId,
|
|
6636
|
+
config.protectedEnvironments
|
|
6637
|
+
);
|
|
6638
|
+
const params = {
|
|
6639
|
+
spaceId: args.spaceId,
|
|
6640
|
+
environmentId: args.environmentId,
|
|
6641
|
+
experienceFragmentId: args.experienceFragmentId
|
|
6642
|
+
};
|
|
6643
|
+
const contentfulClient = createToolClient(config, args);
|
|
6644
|
+
const current = await contentfulClient.experienceFragment.get(params);
|
|
6645
|
+
if (args.version !== current.sys.version) {
|
|
6646
|
+
throw new Error(
|
|
6647
|
+
`Version conflict: the experience fragment has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the experience fragment with get_experience_fragment and retry with the latest sys.version.`
|
|
6648
|
+
);
|
|
6649
|
+
}
|
|
6650
|
+
const experienceFragment = await contentfulClient.experienceFragment.unpublish({
|
|
6651
|
+
...params,
|
|
6652
|
+
version: args.version
|
|
6653
|
+
});
|
|
6654
|
+
return createSuccessResponse(
|
|
6655
|
+
"Experience fragment unpublished successfully",
|
|
6656
|
+
{
|
|
6657
|
+
experienceFragment
|
|
6658
|
+
}
|
|
6659
|
+
);
|
|
6660
|
+
}
|
|
6661
|
+
return withErrorHandling(tool2, "Error unpublishing experience fragment");
|
|
6662
|
+
}
|
|
6663
|
+
|
|
6664
|
+
// src/tools/exo/experience-fragments/register.ts
|
|
6665
|
+
function createExperienceFragmentTools(config) {
|
|
6666
|
+
const getExperienceFragment = getExperienceFragmentTool(config);
|
|
6667
|
+
const listExperienceFragments = listExperienceFragmentsTool(config);
|
|
6668
|
+
const createExperienceFragment = createExperienceFragmentTool(config);
|
|
6669
|
+
const updateExperienceFragment = updateExperienceFragmentTool(config);
|
|
6670
|
+
const deleteExperienceFragment = deleteExperienceFragmentTool(config);
|
|
6671
|
+
const publishExperienceFragment = publishExperienceFragmentTool(config);
|
|
6672
|
+
const unpublishExperienceFragment = unpublishExperienceFragmentTool(config);
|
|
6673
|
+
return {
|
|
6674
|
+
getExperienceFragment: {
|
|
6675
|
+
title: "get_experience_fragment",
|
|
6676
|
+
description: "Get details about a specific ExO experience fragment (a reusable content unit that can be referenced across multiple Experiences and Components).",
|
|
6677
|
+
inputParams: GetExperienceFragmentToolParams.shape,
|
|
6678
|
+
annotations: {
|
|
6679
|
+
readOnlyHint: true,
|
|
6680
|
+
destructiveHint: false,
|
|
6681
|
+
openWorldHint: false
|
|
6682
|
+
},
|
|
6683
|
+
tool: getExperienceFragment
|
|
6684
|
+
},
|
|
6685
|
+
listExperienceFragments: {
|
|
6686
|
+
title: "list_experience_fragments",
|
|
6687
|
+
description: "List ExO experience fragments in a space and environment. Returns a maximum of 10 items per request; use the pageNext cursor (returned in pages.next) to paginate.",
|
|
6688
|
+
inputParams: ListExperienceFragmentsToolParams.shape,
|
|
6689
|
+
annotations: {
|
|
6690
|
+
readOnlyHint: true,
|
|
6691
|
+
destructiveHint: false,
|
|
6692
|
+
openWorldHint: false
|
|
6693
|
+
},
|
|
6694
|
+
tool: listExperienceFragments
|
|
6695
|
+
},
|
|
6696
|
+
createExperienceFragment: {
|
|
6697
|
+
title: "create_experience_fragment",
|
|
6698
|
+
description: "Create a new ExO experience fragment.",
|
|
6699
|
+
inputParams: CreateExperienceFragmentToolParams.shape,
|
|
6700
|
+
annotations: {
|
|
6701
|
+
readOnlyHint: false,
|
|
6702
|
+
destructiveHint: false,
|
|
6703
|
+
idempotentHint: false,
|
|
6704
|
+
openWorldHint: false
|
|
6705
|
+
},
|
|
6706
|
+
tool: createExperienceFragment
|
|
6707
|
+
},
|
|
6708
|
+
updateExperienceFragment: {
|
|
6709
|
+
title: "update_experience_fragment",
|
|
6710
|
+
description: "Update an existing ExO experience fragment. You MUST call get_experience_fragment first to read the current state, then pass the sys.version you received as the version parameter. The handler merges your updates with the existing experience fragment fields, so you only need to provide the fields you want to change. If the version is stale (the experience fragment changed since you read it), the update is rejected and you must re-fetch with get_experience_fragment.",
|
|
6711
|
+
inputParams: UpdateExperienceFragmentToolParams.shape,
|
|
6712
|
+
annotations: {
|
|
6713
|
+
readOnlyHint: false,
|
|
6714
|
+
destructiveHint: false,
|
|
6715
|
+
idempotentHint: false,
|
|
6716
|
+
openWorldHint: false
|
|
6717
|
+
},
|
|
6718
|
+
tool: updateExperienceFragment
|
|
6719
|
+
},
|
|
6720
|
+
deleteExperienceFragment: {
|
|
6721
|
+
title: "delete_experience_fragment",
|
|
6722
|
+
description: "Delete an ExO experience fragment. Two-phase: the first call (without confirm/confirmToken) returns a preview and a confirmToken. To complete the deletion, call again with the same experienceFragmentId, confirm: true, and the confirmToken from the preview.",
|
|
6723
|
+
inputParams: DeleteExperienceFragmentToolParams.shape,
|
|
6724
|
+
annotations: {
|
|
6725
|
+
readOnlyHint: false,
|
|
6726
|
+
destructiveHint: true,
|
|
6727
|
+
idempotentHint: false,
|
|
6728
|
+
openWorldHint: false
|
|
6729
|
+
},
|
|
6730
|
+
tool: deleteExperienceFragment
|
|
6731
|
+
},
|
|
6732
|
+
publishExperienceFragment: {
|
|
6733
|
+
title: "publish_experience_fragment",
|
|
6734
|
+
description: "Publish an ExO experience fragment. You MUST call get_experience_fragment first and pass the returned sys.version as the version parameter. If the version is stale the operation is rejected and you must re-fetch with get_experience_fragment.",
|
|
6735
|
+
inputParams: PublishExperienceFragmentToolParams.shape,
|
|
6736
|
+
annotations: {
|
|
6737
|
+
readOnlyHint: false,
|
|
6738
|
+
destructiveHint: true,
|
|
6739
|
+
idempotentHint: true,
|
|
6740
|
+
openWorldHint: false
|
|
6741
|
+
},
|
|
6742
|
+
tool: publishExperienceFragment
|
|
6743
|
+
},
|
|
6744
|
+
unpublishExperienceFragment: {
|
|
6745
|
+
title: "unpublish_experience_fragment",
|
|
6746
|
+
description: "Unpublish an ExO experience fragment. You MUST call get_experience_fragment first and pass the returned sys.version as the version parameter. If the version is stale the operation is rejected and you must re-fetch with get_experience_fragment.",
|
|
6747
|
+
inputParams: UnpublishExperienceFragmentToolParams.shape,
|
|
6748
|
+
annotations: {
|
|
6749
|
+
readOnlyHint: false,
|
|
6750
|
+
destructiveHint: true,
|
|
6751
|
+
idempotentHint: true,
|
|
6752
|
+
openWorldHint: false
|
|
6753
|
+
},
|
|
6754
|
+
tool: unpublishExperienceFragment
|
|
6755
|
+
}
|
|
6756
|
+
};
|
|
6757
|
+
}
|
|
6758
|
+
|
|
6759
|
+
// src/tools/exo/experience-templates/getExperienceTemplate.ts
|
|
6760
|
+
import { z as z98 } from "zod";
|
|
6761
|
+
var GetExperienceTemplateToolParams = BaseToolSchema.extend({
|
|
6762
|
+
experienceTemplateId: z98.string().describe("The ID of the experience template to retrieve details for")
|
|
6763
|
+
});
|
|
6764
|
+
function getExperienceTemplateTool(config) {
|
|
6765
|
+
async function tool2(args) {
|
|
6766
|
+
const contentfulClient = createToolClient(config, args);
|
|
6767
|
+
const experienceTemplate = await contentfulClient.experienceTemplate.get({
|
|
6768
|
+
spaceId: args.spaceId,
|
|
6769
|
+
environmentId: args.environmentId,
|
|
6770
|
+
experienceTemplateId: args.experienceTemplateId
|
|
6771
|
+
});
|
|
6772
|
+
return createSuccessResponse("Experience template retrieved successfully", {
|
|
6773
|
+
experienceTemplate
|
|
6774
|
+
});
|
|
6775
|
+
}
|
|
6776
|
+
return withErrorHandling(tool2, "Error retrieving experience template");
|
|
6777
|
+
}
|
|
6778
|
+
|
|
6779
|
+
// src/tools/exo/experience-templates/listExperienceTemplates.ts
|
|
6780
|
+
import { z as z99 } from "zod";
|
|
6781
|
+
var ListExperienceTemplatesToolParams = BaseToolSchema.extend({
|
|
6782
|
+
limit: z99.number().optional().describe("Maximum number of experience templates to return (max 10)"),
|
|
6783
|
+
pageNext: z99.string().optional().describe("Cursor token to fetch the next page of results"),
|
|
6784
|
+
pagePrev: z99.string().optional().describe("Cursor token to fetch the previous page of results"),
|
|
6785
|
+
order: z99.string().optional().describe("Order experience templates by this field (e.g. sys.createdAt)")
|
|
6786
|
+
});
|
|
6787
|
+
function listExperienceTemplatesTool(config) {
|
|
6788
|
+
async function tool2(args) {
|
|
6789
|
+
const contentfulClient = createToolClient(config, args);
|
|
6790
|
+
const experienceTemplates = await contentfulClient.experienceTemplate.getMany({
|
|
6791
|
+
spaceId: args.spaceId,
|
|
6792
|
+
environmentId: args.environmentId,
|
|
6793
|
+
query: {
|
|
6794
|
+
limit: Math.min(args.limit || 10, 10),
|
|
6795
|
+
...args.pageNext && { pageNext: args.pageNext },
|
|
6796
|
+
...args.pagePrev && { pagePrev: args.pagePrev },
|
|
6797
|
+
...args.order && { order: args.order }
|
|
6798
|
+
}
|
|
6799
|
+
});
|
|
6800
|
+
const summarized = summarizeData(experienceTemplates, {
|
|
6801
|
+
maxItems: 10,
|
|
6802
|
+
remainingMessage: "To see more experience templates, ask me to retrieve the next page using the pageNext cursor."
|
|
6803
|
+
});
|
|
6804
|
+
return createSuccessResponse("ExperienceTemplates retrieved successfully", {
|
|
6805
|
+
experienceTemplates: summarized,
|
|
6806
|
+
total: experienceTemplates.total,
|
|
6807
|
+
limit: experienceTemplates.limit,
|
|
6808
|
+
pages: experienceTemplates.pages
|
|
6809
|
+
});
|
|
6810
|
+
}
|
|
6811
|
+
return withErrorHandling(tool2, "Error listing experience templates");
|
|
6812
|
+
}
|
|
6813
|
+
|
|
6814
|
+
// src/tools/exo/experience-templates/createExperienceTemplate.ts
|
|
6815
|
+
import { z as z100 } from "zod";
|
|
6816
|
+
var CreateExperienceTemplateToolParams = BaseToolSchema.extend({
|
|
6817
|
+
name: z100.string().describe("The name of the experience template"),
|
|
6818
|
+
description: z100.string().describe("Description of the experience template"),
|
|
6819
|
+
viewports: z100.array(ViewportSchema).describe(
|
|
6820
|
+
"Viewport definitions for the experience template (may be empty)"
|
|
6821
|
+
),
|
|
6822
|
+
contentProperties: z100.array(ContentPropertySchema).describe("Content property definitions (may be empty)"),
|
|
6823
|
+
designProperties: z100.array(DesignPropertySchema).describe("Design property definitions (may be empty)"),
|
|
6824
|
+
componentTree: z100.array(TreeNodeSchema).optional().describe("Optional component tree node definitions"),
|
|
6825
|
+
slots: z100.array(SlotDefinitionSchema).optional().describe("Optional slot definitions"),
|
|
6826
|
+
metadata: ExoMetadataSchema.optional().describe(
|
|
6827
|
+
"Optional ExO metadata (tags, concepts)"
|
|
6828
|
+
)
|
|
6829
|
+
});
|
|
6830
|
+
function createExperienceTemplateTool(config) {
|
|
6831
|
+
async function tool2(args) {
|
|
6832
|
+
assertEnvironmentNotProtected(
|
|
6833
|
+
args.environmentId,
|
|
6834
|
+
config.protectedEnvironments
|
|
6835
|
+
);
|
|
6836
|
+
const contentfulClient = createToolClient(config, args);
|
|
6837
|
+
const experienceTemplate = await contentfulClient.experienceTemplate.create(
|
|
6838
|
+
{ spaceId: args.spaceId, environmentId: args.environmentId },
|
|
6839
|
+
{
|
|
6840
|
+
name: args.name,
|
|
6841
|
+
description: args.description,
|
|
6842
|
+
viewports: args.viewports,
|
|
6843
|
+
contentProperties: args.contentProperties,
|
|
6844
|
+
designProperties: args.designProperties,
|
|
6845
|
+
...args.componentTree && { componentTree: args.componentTree },
|
|
6846
|
+
...args.slots && { slots: args.slots },
|
|
6847
|
+
...args.metadata && { metadata: args.metadata }
|
|
6848
|
+
}
|
|
6849
|
+
);
|
|
6850
|
+
return createSuccessResponse("Experience template created successfully", {
|
|
6851
|
+
experienceTemplate
|
|
6852
|
+
});
|
|
6853
|
+
}
|
|
6854
|
+
return withErrorHandling(tool2, "Error creating experience template");
|
|
6855
|
+
}
|
|
6856
|
+
|
|
6857
|
+
// src/tools/exo/experience-templates/upsertExperienceTemplate.ts
|
|
6858
|
+
import { z as z101 } from "zod";
|
|
6859
|
+
var UpsertExperienceTemplateToolParams = BaseToolSchema.extend({
|
|
6860
|
+
experienceTemplateId: z101.string().describe("The ID of the experience template to update"),
|
|
6861
|
+
version: z101.number().describe(
|
|
6862
|
+
"REQUIRED. The experience template's sys.version as returned by get_experience_template. You must call get_experience_template first to read the current state and version. The update is rejected if this does not match the current version, which means the experience template changed since you read it."
|
|
6863
|
+
),
|
|
6864
|
+
name: z101.string().optional().describe("The name of the experience template"),
|
|
6865
|
+
description: z101.string().optional().describe("Description of the experience template"),
|
|
6866
|
+
viewports: z101.array(ViewportSchema).optional().describe("Viewport definitions; replaces existing viewports if provided"),
|
|
6867
|
+
contentProperties: z101.array(ContentPropertySchema).optional().describe("Content property definitions; replaces existing if provided"),
|
|
6868
|
+
designProperties: z101.array(DesignPropertySchema).optional().describe("Design property definitions; replaces existing if provided"),
|
|
6869
|
+
componentTree: z101.array(TreeNodeSchema).optional().describe("Component tree node definitions; replaces existing if provided"),
|
|
6870
|
+
slots: z101.array(SlotDefinitionSchema).optional().describe("Slot definitions; replaces existing if provided"),
|
|
6871
|
+
metadata: ExoMetadataSchema.optional().describe(
|
|
6872
|
+
"ExO metadata (tags, concepts); replaces existing if provided"
|
|
6873
|
+
)
|
|
6874
|
+
});
|
|
6875
|
+
function upsertExperienceTemplateTool(config) {
|
|
6876
|
+
async function tool2(args) {
|
|
6877
|
+
assertEnvironmentNotProtected(
|
|
6878
|
+
args.environmentId,
|
|
6879
|
+
config.protectedEnvironments
|
|
6880
|
+
);
|
|
6881
|
+
const params = {
|
|
6882
|
+
spaceId: args.spaceId,
|
|
6883
|
+
environmentId: args.environmentId,
|
|
6884
|
+
experienceTemplateId: args.experienceTemplateId
|
|
6885
|
+
};
|
|
6886
|
+
const contentfulClient = createToolClient(config, args);
|
|
6887
|
+
const current = await contentfulClient.experienceTemplate.get(params);
|
|
6888
|
+
if (args.version !== current.sys.version) {
|
|
6889
|
+
throw new Error(
|
|
6890
|
+
`Version conflict: the experience template has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the experience template with get_experience_template and retry the update with the latest sys.version.`
|
|
6891
|
+
);
|
|
6892
|
+
}
|
|
6893
|
+
const experienceTemplate = await contentfulClient.experienceTemplate.upsert(
|
|
6894
|
+
params,
|
|
6895
|
+
{
|
|
6896
|
+
sys: {
|
|
6897
|
+
id: current.sys.id,
|
|
6898
|
+
type: "ExperienceTemplate",
|
|
6899
|
+
version: current.sys.version
|
|
6900
|
+
},
|
|
6901
|
+
name: args.name ?? current.name,
|
|
6902
|
+
description: args.description ?? current.description,
|
|
6903
|
+
viewports: args.viewports ?? current.viewports,
|
|
6904
|
+
contentProperties: args.contentProperties ?? current.contentProperties,
|
|
6905
|
+
designProperties: args.designProperties ?? current.designProperties,
|
|
6906
|
+
...args.componentTree ?? current.componentTree ? { componentTree: args.componentTree ?? current.componentTree } : {},
|
|
6907
|
+
...args.slots ?? current.slots ? { slots: args.slots ?? current.slots } : {},
|
|
6908
|
+
...args.metadata ?? current.metadata ? { metadata: args.metadata ?? current.metadata } : {},
|
|
6909
|
+
...current.dataAssemblies ? { dataAssemblies: current.dataAssemblies } : {}
|
|
6910
|
+
}
|
|
6911
|
+
);
|
|
6912
|
+
return createSuccessResponse("Experience template updated successfully", {
|
|
6913
|
+
experienceTemplate
|
|
6914
|
+
});
|
|
6915
|
+
}
|
|
6916
|
+
return withErrorHandling(tool2, "Error updating experience template");
|
|
6917
|
+
}
|
|
6918
|
+
|
|
6919
|
+
// src/tools/exo/experience-templates/deleteExperienceTemplate.ts
|
|
6920
|
+
import { z as z102 } from "zod";
|
|
6921
|
+
var DeleteExperienceTemplateToolParams = BaseToolSchema.extend({
|
|
6922
|
+
experienceTemplateId: z102.string().describe("The ID of the experience template to delete"),
|
|
6923
|
+
confirm: z102.boolean().optional().describe(
|
|
6924
|
+
"Set to true on the second call to actually perform the deletion. Required together with confirmToken."
|
|
6925
|
+
),
|
|
6926
|
+
confirmToken: z102.string().optional().describe(
|
|
6927
|
+
"Token returned by the preview call; must be supplied with confirm: true."
|
|
6928
|
+
)
|
|
6929
|
+
});
|
|
6930
|
+
function deleteExperienceTemplateTool(config) {
|
|
6931
|
+
async function tool2(args) {
|
|
6932
|
+
assertEnvironmentNotProtected(
|
|
6933
|
+
args.environmentId,
|
|
6934
|
+
config.protectedEnvironments
|
|
6935
|
+
);
|
|
6936
|
+
const params = {
|
|
6937
|
+
spaceId: args.spaceId,
|
|
6938
|
+
environmentId: args.environmentId,
|
|
6939
|
+
experienceTemplateId: args.experienceTemplateId
|
|
6940
|
+
};
|
|
6941
|
+
const contentfulClient = createToolClient(config, args);
|
|
6942
|
+
const experienceTemplate = await contentfulClient.experienceTemplate.get(params);
|
|
6943
|
+
const expectedToken = buildConfirmToken(
|
|
6944
|
+
"experienceTemplate",
|
|
6945
|
+
args.experienceTemplateId,
|
|
6946
|
+
experienceTemplate.sys.version
|
|
6947
|
+
);
|
|
6948
|
+
if (args.confirm !== true || args.confirmToken !== expectedToken) {
|
|
6949
|
+
return createSuccessResponse(
|
|
6950
|
+
`${CONFIRMATION_MESSAGE_PREFIX} experience template`,
|
|
6951
|
+
buildConfirmationPreview(
|
|
6952
|
+
"experienceTemplate",
|
|
6953
|
+
args.experienceTemplateId,
|
|
6954
|
+
{ experienceTemplate },
|
|
6955
|
+
expectedToken
|
|
6956
|
+
)
|
|
6957
|
+
);
|
|
6958
|
+
}
|
|
6959
|
+
await contentfulClient.experienceTemplate.delete(params);
|
|
6960
|
+
return createSuccessResponse("Experience template deleted successfully", {
|
|
6961
|
+
experienceTemplateId: args.experienceTemplateId
|
|
6962
|
+
});
|
|
6963
|
+
}
|
|
6964
|
+
return withErrorHandling(tool2, "Error deleting experience template");
|
|
6965
|
+
}
|
|
6966
|
+
|
|
6967
|
+
// src/tools/exo/experience-templates/publishExperienceTemplate.ts
|
|
6968
|
+
import { z as z103 } from "zod";
|
|
6969
|
+
var PublishExperienceTemplateToolParams = BaseToolSchema.extend({
|
|
6970
|
+
experienceTemplateId: z103.string().describe("The ID of the experience template to publish"),
|
|
6971
|
+
version: z103.number().describe(
|
|
6972
|
+
"REQUIRED. The experience template's sys.version as returned by get_experience_template. You must call get_experience_template first to read the current state and version. The publish is rejected if this does not match the current version, which means the experience template changed since you read it."
|
|
6973
|
+
)
|
|
6974
|
+
});
|
|
6975
|
+
function publishExperienceTemplateTool(config) {
|
|
6976
|
+
async function tool2(args) {
|
|
6977
|
+
assertEnvironmentNotProtected(
|
|
6978
|
+
args.environmentId,
|
|
6979
|
+
config.protectedEnvironments
|
|
6980
|
+
);
|
|
6981
|
+
const params = {
|
|
6982
|
+
spaceId: args.spaceId,
|
|
6983
|
+
environmentId: args.environmentId,
|
|
6984
|
+
experienceTemplateId: args.experienceTemplateId
|
|
6985
|
+
};
|
|
6986
|
+
const contentfulClient = createToolClient(config, args);
|
|
6987
|
+
const current = await contentfulClient.experienceTemplate.get(params);
|
|
6988
|
+
if (args.version !== current.sys.version) {
|
|
6989
|
+
throw new Error(
|
|
6990
|
+
`Version conflict: the experience template has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the experience template with get_experience_template and retry with the latest sys.version.`
|
|
6991
|
+
);
|
|
6992
|
+
}
|
|
6993
|
+
const experienceTemplate = await contentfulClient.experienceTemplate.publish({
|
|
6994
|
+
...params,
|
|
6995
|
+
version: args.version
|
|
6996
|
+
});
|
|
6997
|
+
return createSuccessResponse("Experience template published successfully", {
|
|
6998
|
+
experienceTemplate
|
|
6999
|
+
});
|
|
7000
|
+
}
|
|
7001
|
+
return withErrorHandling(tool2, "Error publishing experience template");
|
|
7002
|
+
}
|
|
7003
|
+
|
|
7004
|
+
// src/tools/exo/experience-templates/unpublishExperienceTemplate.ts
|
|
7005
|
+
import { z as z104 } from "zod";
|
|
7006
|
+
var UnpublishExperienceTemplateToolParams = BaseToolSchema.extend({
|
|
7007
|
+
experienceTemplateId: z104.string().describe("The ID of the experience template to unpublish"),
|
|
7008
|
+
version: z104.number().describe(
|
|
7009
|
+
"REQUIRED. The experience template's sys.version as returned by get_experience_template. You must call get_experience_template first to read the current state and version. The unpublish is rejected if this does not match the current version, which means the experience template changed since you read it."
|
|
7010
|
+
)
|
|
7011
|
+
});
|
|
7012
|
+
function unpublishExperienceTemplateTool(config) {
|
|
7013
|
+
async function tool2(args) {
|
|
7014
|
+
assertEnvironmentNotProtected(
|
|
7015
|
+
args.environmentId,
|
|
7016
|
+
config.protectedEnvironments
|
|
7017
|
+
);
|
|
7018
|
+
const params = {
|
|
7019
|
+
spaceId: args.spaceId,
|
|
7020
|
+
environmentId: args.environmentId,
|
|
7021
|
+
experienceTemplateId: args.experienceTemplateId
|
|
7022
|
+
};
|
|
7023
|
+
const contentfulClient = createToolClient(config, args);
|
|
7024
|
+
const current = await contentfulClient.experienceTemplate.get(params);
|
|
7025
|
+
if (args.version !== current.sys.version) {
|
|
7026
|
+
throw new Error(
|
|
7027
|
+
`Version conflict: the experience template has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the experience template with get_experience_template and retry with the latest sys.version.`
|
|
7028
|
+
);
|
|
7029
|
+
}
|
|
7030
|
+
const experienceTemplate = await contentfulClient.experienceTemplate.unpublish({
|
|
7031
|
+
...params,
|
|
7032
|
+
version: args.version
|
|
7033
|
+
});
|
|
7034
|
+
return createSuccessResponse(
|
|
7035
|
+
"Experience template unpublished successfully",
|
|
7036
|
+
{
|
|
7037
|
+
experienceTemplate
|
|
7038
|
+
}
|
|
7039
|
+
);
|
|
7040
|
+
}
|
|
7041
|
+
return withErrorHandling(tool2, "Error unpublishing experience template");
|
|
7042
|
+
}
|
|
7043
|
+
|
|
7044
|
+
// src/tools/exo/experience-templates/register.ts
|
|
7045
|
+
function createExperienceTemplateTools(config) {
|
|
7046
|
+
const getExperienceTemplate = getExperienceTemplateTool(config);
|
|
7047
|
+
const listExperienceTemplates = listExperienceTemplatesTool(config);
|
|
7048
|
+
const createExperienceTemplate = createExperienceTemplateTool(config);
|
|
7049
|
+
const upsertExperienceTemplate = upsertExperienceTemplateTool(config);
|
|
7050
|
+
const deleteExperienceTemplate = deleteExperienceTemplateTool(config);
|
|
7051
|
+
const publishExperienceTemplate = publishExperienceTemplateTool(config);
|
|
7052
|
+
const unpublishExperienceTemplate = unpublishExperienceTemplateTool(config);
|
|
7053
|
+
return {
|
|
7054
|
+
getExperienceTemplate: {
|
|
7055
|
+
title: "get_experience_template",
|
|
7056
|
+
description: "Get details about a specific ExO experience template (a layout definition that backs experience-template-based Experiences).",
|
|
7057
|
+
inputParams: GetExperienceTemplateToolParams.shape,
|
|
7058
|
+
annotations: {
|
|
7059
|
+
readOnlyHint: true,
|
|
7060
|
+
destructiveHint: false,
|
|
7061
|
+
openWorldHint: false
|
|
7062
|
+
},
|
|
7063
|
+
tool: getExperienceTemplate
|
|
7064
|
+
},
|
|
7065
|
+
listExperienceTemplates: {
|
|
7066
|
+
title: "list_experience_templates",
|
|
7067
|
+
description: "List ExO experience templates in a space and environment. Returns a maximum of 10 items per request; use the pageNext cursor (returned in pages.next) to paginate.",
|
|
7068
|
+
inputParams: ListExperienceTemplatesToolParams.shape,
|
|
7069
|
+
annotations: {
|
|
7070
|
+
readOnlyHint: true,
|
|
7071
|
+
destructiveHint: false,
|
|
7072
|
+
openWorldHint: false
|
|
7073
|
+
},
|
|
7074
|
+
tool: listExperienceTemplates
|
|
7075
|
+
},
|
|
7076
|
+
createExperienceTemplate: {
|
|
7077
|
+
title: "create_experience_template",
|
|
7078
|
+
description: "Create a new ExO experience template.",
|
|
7079
|
+
inputParams: CreateExperienceTemplateToolParams.shape,
|
|
7080
|
+
annotations: {
|
|
7081
|
+
readOnlyHint: false,
|
|
7082
|
+
destructiveHint: false,
|
|
7083
|
+
idempotentHint: false,
|
|
7084
|
+
openWorldHint: false
|
|
7085
|
+
},
|
|
7086
|
+
tool: createExperienceTemplate
|
|
7087
|
+
},
|
|
7088
|
+
upsertExperienceTemplate: {
|
|
7089
|
+
title: "upsert_experience_template",
|
|
7090
|
+
description: "Update an existing ExO experience template. You MUST call get_experience_template first to read the current state, then pass the sys.version you received as the version parameter. The handler merges your updates with the existing experience template fields, so you only need to provide the fields you want to change. If the version is stale (the experience template changed since you read it), the update is rejected and you must re-fetch with get_experience_template.",
|
|
7091
|
+
inputParams: UpsertExperienceTemplateToolParams.shape,
|
|
7092
|
+
annotations: {
|
|
7093
|
+
readOnlyHint: false,
|
|
7094
|
+
destructiveHint: false,
|
|
7095
|
+
idempotentHint: false,
|
|
7096
|
+
openWorldHint: false
|
|
7097
|
+
},
|
|
7098
|
+
tool: upsertExperienceTemplate
|
|
7099
|
+
},
|
|
7100
|
+
deleteExperienceTemplate: {
|
|
7101
|
+
title: "delete_experience_template",
|
|
7102
|
+
description: "Delete an ExO experience template. Two-phase: the first call (without confirm/confirmToken) returns a preview and a confirmToken. To complete the deletion, call again with the same experienceTemplateId, confirm: true, and the confirmToken from the preview.",
|
|
7103
|
+
inputParams: DeleteExperienceTemplateToolParams.shape,
|
|
7104
|
+
annotations: {
|
|
7105
|
+
readOnlyHint: false,
|
|
7106
|
+
destructiveHint: true,
|
|
7107
|
+
idempotentHint: false,
|
|
7108
|
+
openWorldHint: false
|
|
7109
|
+
},
|
|
7110
|
+
tool: deleteExperienceTemplate
|
|
7111
|
+
},
|
|
7112
|
+
publishExperienceTemplate: {
|
|
7113
|
+
title: "publish_experience_template",
|
|
7114
|
+
description: "Publish an ExO experience template. You MUST call get_experience_template first and pass the returned sys.version as the version parameter. If the version is stale the operation is rejected and you must re-fetch with get_experience_template.",
|
|
7115
|
+
inputParams: PublishExperienceTemplateToolParams.shape,
|
|
7116
|
+
annotations: {
|
|
7117
|
+
readOnlyHint: false,
|
|
7118
|
+
destructiveHint: true,
|
|
7119
|
+
idempotentHint: true,
|
|
7120
|
+
openWorldHint: false
|
|
7121
|
+
},
|
|
7122
|
+
tool: publishExperienceTemplate
|
|
7123
|
+
},
|
|
7124
|
+
unpublishExperienceTemplate: {
|
|
7125
|
+
title: "unpublish_experience_template",
|
|
7126
|
+
description: "Unpublish an ExO experience template. You MUST call get_experience_template first and pass the returned sys.version as the version parameter. If the version is stale the operation is rejected and you must re-fetch with get_experience_template.",
|
|
7127
|
+
inputParams: UnpublishExperienceTemplateToolParams.shape,
|
|
7128
|
+
annotations: {
|
|
7129
|
+
readOnlyHint: false,
|
|
7130
|
+
destructiveHint: true,
|
|
7131
|
+
idempotentHint: true,
|
|
7132
|
+
openWorldHint: false
|
|
7133
|
+
},
|
|
7134
|
+
tool: unpublishExperienceTemplate
|
|
7135
|
+
}
|
|
7136
|
+
};
|
|
7137
|
+
}
|
|
7138
|
+
|
|
7139
|
+
// src/tools/exo/experiences/getExperience.ts
|
|
7140
|
+
import { z as z105 } from "zod";
|
|
7141
|
+
var GetExperienceToolParams = BaseToolSchema.extend({
|
|
7142
|
+
experienceId: z105.string().describe("The ID of the experience to retrieve")
|
|
7143
|
+
});
|
|
7144
|
+
function getExperienceTool(config) {
|
|
7145
|
+
async function tool2(args) {
|
|
7146
|
+
const contentfulClient = createToolClient(config, args);
|
|
7147
|
+
const experience = await contentfulClient.experience.get({
|
|
7148
|
+
spaceId: args.spaceId,
|
|
7149
|
+
environmentId: args.environmentId,
|
|
7150
|
+
experienceId: args.experienceId
|
|
7151
|
+
});
|
|
7152
|
+
return createSuccessResponse("Experience retrieved successfully", {
|
|
7153
|
+
experience
|
|
7154
|
+
});
|
|
7155
|
+
}
|
|
7156
|
+
return withErrorHandling(tool2, "Error retrieving experience");
|
|
7157
|
+
}
|
|
7158
|
+
|
|
7159
|
+
// src/tools/exo/experiences/listExperiences.ts
|
|
7160
|
+
import { z as z106 } from "zod";
|
|
7161
|
+
var ListExperiencesToolParams = BaseToolSchema.extend({
|
|
7162
|
+
limit: z106.number().optional().describe("Maximum number of experiences to return (max 10)"),
|
|
7163
|
+
pageNext: z106.string().optional().describe("Cursor token to fetch the next page of results"),
|
|
7164
|
+
pagePrev: z106.string().optional().describe("Cursor token to fetch the previous page of results"),
|
|
7165
|
+
order: z106.string().optional().describe("Order experiences by this field (e.g. sys.createdAt)")
|
|
7166
|
+
});
|
|
7167
|
+
function listExperiencesTool(config) {
|
|
7168
|
+
async function tool2(args) {
|
|
7169
|
+
const contentfulClient = createToolClient(config, args);
|
|
7170
|
+
const experiences = await contentfulClient.experience.getMany({
|
|
7171
|
+
spaceId: args.spaceId,
|
|
7172
|
+
environmentId: args.environmentId,
|
|
7173
|
+
query: {
|
|
7174
|
+
limit: Math.min(args.limit || 10, 10),
|
|
7175
|
+
...args.pageNext && { pageNext: args.pageNext },
|
|
7176
|
+
...args.pagePrev && { pagePrev: args.pagePrev },
|
|
7177
|
+
...args.order && { order: args.order }
|
|
7178
|
+
}
|
|
7179
|
+
});
|
|
7180
|
+
const summarized = summarizeData(experiences, {
|
|
7181
|
+
maxItems: 10,
|
|
7182
|
+
remainingMessage: "To see more experiences, ask me to retrieve the next page using the pageNext cursor."
|
|
7183
|
+
});
|
|
7184
|
+
return createSuccessResponse("Experiences retrieved successfully", {
|
|
7185
|
+
experiences: summarized,
|
|
7186
|
+
total: experiences.total,
|
|
7187
|
+
limit: experiences.limit,
|
|
7188
|
+
pages: experiences.pages
|
|
7189
|
+
});
|
|
7190
|
+
}
|
|
7191
|
+
return withErrorHandling(tool2, "Error listing experiences");
|
|
7192
|
+
}
|
|
7193
|
+
|
|
7194
|
+
// src/tools/exo/experiences/createExperience.ts
|
|
7195
|
+
import { z as z107 } from "zod";
|
|
7196
|
+
var CreateExperienceToolParams = BaseToolSchema.extend({
|
|
7197
|
+
name: z107.string().describe("The name of the experience"),
|
|
7198
|
+
description: z107.string().describe("Description of the experience"),
|
|
7199
|
+
experienceTemplate: ExperienceTemplateResourceLinkSchema.describe(
|
|
7200
|
+
"Resource link to the ExperienceTemplate this experience is backed by"
|
|
7201
|
+
),
|
|
7202
|
+
viewports: z107.array(ViewportSchema).describe("Viewport definitions for the experience (may be empty)"),
|
|
7203
|
+
designProperties: z107.record(z107.string(), DimensionedDesignPropertyValueSchema).describe(
|
|
7204
|
+
"Design property values keyed by property ID. Each value is a dimensioned map (viewport ID \u2192 design value). May be an empty object."
|
|
7205
|
+
),
|
|
7206
|
+
contentBindings: ExperienceContentBindingsSchema.optional().describe(
|
|
7207
|
+
"Optional content bindings linking this experience to a data assembly"
|
|
7208
|
+
),
|
|
7209
|
+
slots: z107.record(z107.string(), z107.array(ExperienceSlotNodeSchema)).optional().describe(
|
|
7210
|
+
"Optional slot contents keyed by slot ID. Each value is an array of ExperienceFragmentNode or InlineExperienceFragmentNode."
|
|
7211
|
+
),
|
|
7212
|
+
metadata: ExperienceMetadataSchema.optional().describe(
|
|
7213
|
+
"Optional ExO metadata (tags, concepts)"
|
|
7214
|
+
)
|
|
7215
|
+
});
|
|
7216
|
+
function createExperienceTool(config) {
|
|
7217
|
+
async function tool2(args) {
|
|
7218
|
+
assertEnvironmentNotProtected(
|
|
7219
|
+
args.environmentId,
|
|
7220
|
+
config.protectedEnvironments
|
|
7221
|
+
);
|
|
7222
|
+
const contentfulClient = createToolClient(config, args);
|
|
7223
|
+
const experience = await contentfulClient.experience.create(
|
|
7224
|
+
{ spaceId: args.spaceId, environmentId: args.environmentId },
|
|
7225
|
+
{
|
|
7226
|
+
name: args.name,
|
|
7227
|
+
description: args.description,
|
|
7228
|
+
experienceTemplate: args.experienceTemplate,
|
|
7229
|
+
viewports: args.viewports,
|
|
7230
|
+
designProperties: args.designProperties,
|
|
7231
|
+
...args.contentBindings && { contentBindings: args.contentBindings },
|
|
7232
|
+
...args.slots && { slots: args.slots },
|
|
7233
|
+
...args.metadata && { metadata: args.metadata }
|
|
7234
|
+
}
|
|
7235
|
+
);
|
|
7236
|
+
return createSuccessResponse("Experience created successfully", {
|
|
7237
|
+
experience
|
|
7238
|
+
});
|
|
7239
|
+
}
|
|
7240
|
+
return withErrorHandling(tool2, "Error creating experience");
|
|
7241
|
+
}
|
|
7242
|
+
|
|
7243
|
+
// src/tools/exo/experiences/upsertExperience.ts
|
|
7244
|
+
import { z as z108 } from "zod";
|
|
7245
|
+
var UpsertExperienceToolParams = BaseToolSchema.extend({
|
|
7246
|
+
experienceId: z108.string().describe("The ID of the experience to update"),
|
|
7247
|
+
version: z108.number().describe(
|
|
7248
|
+
"REQUIRED. The experience's sys.version as returned by get_experience. You must call get_experience first to read the current state and version. The update is rejected if this does not match the current version, which means the experience changed since you read it."
|
|
7249
|
+
),
|
|
7250
|
+
name: z108.string().optional().describe("The name of the experience"),
|
|
7251
|
+
description: z108.string().optional().describe("Description of the experience"),
|
|
7252
|
+
viewports: z108.array(ViewportSchema).optional().describe("Viewport definitions; replaces existing viewports if provided"),
|
|
7253
|
+
designProperties: z108.record(z108.string(), DimensionedDesignPropertyValueSchema).optional().describe(
|
|
7254
|
+
"Design property values keyed by property ID; replaces existing if provided"
|
|
7255
|
+
),
|
|
7256
|
+
contentBindings: ExperienceContentBindingsSchema.optional().describe(
|
|
7257
|
+
"Content bindings linking this experience to a data assembly; replaces existing if provided"
|
|
7258
|
+
),
|
|
7259
|
+
slots: z108.record(z108.string(), z108.array(ExperienceSlotNodeSchema)).optional().describe("Slot contents keyed by slot ID; replaces existing if provided"),
|
|
7260
|
+
metadata: ExperienceMetadataSchema.optional().describe(
|
|
7261
|
+
"ExO metadata (tags, concepts); replaces existing if provided"
|
|
7262
|
+
)
|
|
7263
|
+
});
|
|
7264
|
+
function upsertExperienceTool(config) {
|
|
7265
|
+
async function tool2(args) {
|
|
7266
|
+
assertEnvironmentNotProtected(
|
|
7267
|
+
args.environmentId,
|
|
7268
|
+
config.protectedEnvironments
|
|
7269
|
+
);
|
|
7270
|
+
const params = {
|
|
7271
|
+
spaceId: args.spaceId,
|
|
7272
|
+
environmentId: args.environmentId,
|
|
7273
|
+
experienceId: args.experienceId
|
|
7274
|
+
};
|
|
7275
|
+
const contentfulClient = createToolClient(config, args);
|
|
7276
|
+
const current = await contentfulClient.experience.get(params);
|
|
7277
|
+
if (args.version !== current.sys.version) {
|
|
7278
|
+
throw new Error(
|
|
7279
|
+
`Version conflict: the experience has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the experience with get_experience and retry the update with the latest sys.version.`
|
|
7280
|
+
);
|
|
7281
|
+
}
|
|
7282
|
+
const experience = await contentfulClient.experience.upsert(params, {
|
|
7283
|
+
sys: {
|
|
7284
|
+
id: current.sys.id,
|
|
7285
|
+
type: "Experience",
|
|
7286
|
+
version: current.sys.version
|
|
7287
|
+
},
|
|
7288
|
+
name: args.name ?? current.name,
|
|
7289
|
+
description: args.description ?? current.description,
|
|
7290
|
+
viewports: args.viewports ?? current.viewports,
|
|
7291
|
+
designProperties: args.designProperties ?? current.designProperties,
|
|
7292
|
+
...args.contentBindings ?? current.contentBindings ? { contentBindings: args.contentBindings ?? current.contentBindings } : {},
|
|
7293
|
+
...args.slots ?? current.slots ? { slots: args.slots ?? current.slots } : {},
|
|
7294
|
+
...args.metadata ?? current.metadata ? { metadata: args.metadata ?? current.metadata } : {}
|
|
7295
|
+
});
|
|
7296
|
+
return createSuccessResponse("Experience updated successfully", {
|
|
7297
|
+
experience
|
|
7298
|
+
});
|
|
7299
|
+
}
|
|
7300
|
+
return withErrorHandling(tool2, "Error updating experience");
|
|
7301
|
+
}
|
|
7302
|
+
|
|
7303
|
+
// src/tools/exo/experiences/deleteExperience.ts
|
|
7304
|
+
import { z as z109 } from "zod";
|
|
7305
|
+
var DeleteExperienceToolParams = BaseToolSchema.extend({
|
|
7306
|
+
experienceId: z109.string().describe("The ID of the experience to delete"),
|
|
7307
|
+
confirm: z109.boolean().optional().describe(
|
|
7308
|
+
"Set to true on the second call to actually perform the deletion. Required together with confirmToken."
|
|
7309
|
+
),
|
|
7310
|
+
confirmToken: z109.string().optional().describe(
|
|
7311
|
+
"Token returned by the preview call; must be supplied with confirm: true."
|
|
7312
|
+
)
|
|
7313
|
+
});
|
|
7314
|
+
function deleteExperienceTool(config) {
|
|
7315
|
+
async function tool2(args) {
|
|
7316
|
+
assertEnvironmentNotProtected(
|
|
7317
|
+
args.environmentId,
|
|
7318
|
+
config.protectedEnvironments
|
|
7319
|
+
);
|
|
7320
|
+
const params = {
|
|
7321
|
+
spaceId: args.spaceId,
|
|
7322
|
+
environmentId: args.environmentId,
|
|
7323
|
+
experienceId: args.experienceId
|
|
7324
|
+
};
|
|
7325
|
+
const contentfulClient = createToolClient(config, args);
|
|
7326
|
+
const experience = await contentfulClient.experience.get(params);
|
|
7327
|
+
const expectedToken = buildConfirmToken(
|
|
7328
|
+
"experience",
|
|
7329
|
+
args.experienceId,
|
|
7330
|
+
experience.sys.version
|
|
7331
|
+
);
|
|
7332
|
+
if (args.confirm !== true || args.confirmToken !== expectedToken) {
|
|
7333
|
+
return createSuccessResponse(
|
|
7334
|
+
`${CONFIRMATION_MESSAGE_PREFIX} experience`,
|
|
7335
|
+
buildConfirmationPreview(
|
|
7336
|
+
"experience",
|
|
7337
|
+
args.experienceId,
|
|
7338
|
+
{ experience },
|
|
7339
|
+
expectedToken
|
|
7340
|
+
)
|
|
7341
|
+
);
|
|
7342
|
+
}
|
|
7343
|
+
await contentfulClient.experience.delete(params);
|
|
7344
|
+
return createSuccessResponse("Experience deleted successfully", {
|
|
7345
|
+
experienceId: args.experienceId
|
|
7346
|
+
});
|
|
7347
|
+
}
|
|
7348
|
+
return withErrorHandling(tool2, "Error deleting experience");
|
|
7349
|
+
}
|
|
7350
|
+
|
|
7351
|
+
// src/tools/exo/experiences/publishExperience.ts
|
|
7352
|
+
import { z as z110 } from "zod";
|
|
7353
|
+
var PublishExperienceToolParams = BaseToolSchema.extend({
|
|
7354
|
+
experienceId: z110.string().describe("The ID of the experience to publish"),
|
|
7355
|
+
version: z110.number().describe(
|
|
7356
|
+
"REQUIRED. The experience's sys.version as returned by get_experience. You must call get_experience first to read the current state and version. The publish is rejected if this does not match the current version, which means the experience changed since you read it."
|
|
7357
|
+
)
|
|
7358
|
+
});
|
|
7359
|
+
function publishExperienceTool(config) {
|
|
7360
|
+
async function tool2(args) {
|
|
7361
|
+
assertEnvironmentNotProtected(
|
|
7362
|
+
args.environmentId,
|
|
7363
|
+
config.protectedEnvironments
|
|
7364
|
+
);
|
|
7365
|
+
const params = {
|
|
7366
|
+
spaceId: args.spaceId,
|
|
7367
|
+
environmentId: args.environmentId,
|
|
7368
|
+
experienceId: args.experienceId
|
|
7369
|
+
};
|
|
7370
|
+
const contentfulClient = createToolClient(config, args);
|
|
7371
|
+
const current = await contentfulClient.experience.get(params);
|
|
7372
|
+
if (args.version !== current.sys.version) {
|
|
7373
|
+
throw new Error(
|
|
7374
|
+
`Version conflict: the experience has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the experience with get_experience and retry with the latest sys.version.`
|
|
7375
|
+
);
|
|
7376
|
+
}
|
|
7377
|
+
const experience = await contentfulClient.experience.publish({
|
|
7378
|
+
...params,
|
|
7379
|
+
version: args.version
|
|
7380
|
+
});
|
|
7381
|
+
return createSuccessResponse("Experience published successfully", {
|
|
7382
|
+
experience
|
|
7383
|
+
});
|
|
7384
|
+
}
|
|
7385
|
+
return withErrorHandling(tool2, "Error publishing experience");
|
|
7386
|
+
}
|
|
7387
|
+
|
|
7388
|
+
// src/tools/exo/experiences/unpublishExperience.ts
|
|
7389
|
+
import { z as z111 } from "zod";
|
|
7390
|
+
var UnpublishExperienceToolParams = BaseToolSchema.extend({
|
|
7391
|
+
experienceId: z111.string().describe("The ID of the experience to unpublish"),
|
|
7392
|
+
version: z111.number().describe(
|
|
7393
|
+
"REQUIRED. The experience's sys.version as returned by get_experience. You must call get_experience first to read the current state and version. The unpublish is rejected if this does not match the current version, which means the experience changed since you read it."
|
|
7394
|
+
)
|
|
7395
|
+
});
|
|
7396
|
+
function unpublishExperienceTool(config) {
|
|
7397
|
+
async function tool2(args) {
|
|
7398
|
+
assertEnvironmentNotProtected(
|
|
7399
|
+
args.environmentId,
|
|
7400
|
+
config.protectedEnvironments
|
|
7401
|
+
);
|
|
7402
|
+
const params = {
|
|
7403
|
+
spaceId: args.spaceId,
|
|
7404
|
+
environmentId: args.environmentId,
|
|
7405
|
+
experienceId: args.experienceId
|
|
7406
|
+
};
|
|
7407
|
+
const contentfulClient = createToolClient(config, args);
|
|
7408
|
+
const current = await contentfulClient.experience.get(params);
|
|
7409
|
+
if (args.version !== current.sys.version) {
|
|
7410
|
+
throw new Error(
|
|
7411
|
+
`Version conflict: the experience has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the experience with get_experience and retry with the latest sys.version.`
|
|
7412
|
+
);
|
|
7413
|
+
}
|
|
7414
|
+
const experience = await contentfulClient.experience.unpublish({
|
|
7415
|
+
...params,
|
|
7416
|
+
version: args.version
|
|
7417
|
+
});
|
|
7418
|
+
return createSuccessResponse("Experience unpublished successfully", {
|
|
7419
|
+
experience
|
|
7420
|
+
});
|
|
7421
|
+
}
|
|
7422
|
+
return withErrorHandling(tool2, "Error unpublishing experience");
|
|
7423
|
+
}
|
|
7424
|
+
|
|
7425
|
+
// src/tools/exo/experiences/register.ts
|
|
7426
|
+
function createExperienceTools(config) {
|
|
7427
|
+
const getExperience = getExperienceTool(config);
|
|
7428
|
+
const listExperiences = listExperiencesTool(config);
|
|
7429
|
+
const createExperience = createExperienceTool(config);
|
|
7430
|
+
const upsertExperience = upsertExperienceTool(config);
|
|
7431
|
+
const deleteExperience = deleteExperienceTool(config);
|
|
7432
|
+
const publishExperience = publishExperienceTool(config);
|
|
7433
|
+
const unpublishExperience = unpublishExperienceTool(config);
|
|
7434
|
+
return {
|
|
7435
|
+
getExperience: {
|
|
7436
|
+
title: "get_experience",
|
|
7437
|
+
description: "Get details about a specific ExO experience (a concrete page or screen that composes a root Component with content and design settings, backed by an ExperienceTemplate).",
|
|
7438
|
+
inputParams: GetExperienceToolParams.shape,
|
|
7439
|
+
annotations: {
|
|
7440
|
+
readOnlyHint: true,
|
|
7441
|
+
destructiveHint: false,
|
|
7442
|
+
openWorldHint: false
|
|
7443
|
+
},
|
|
7444
|
+
tool: getExperience
|
|
7445
|
+
},
|
|
7446
|
+
listExperiences: {
|
|
7447
|
+
title: "list_experiences",
|
|
7448
|
+
description: "List ExO experiences in a space and environment. Returns a maximum of 10 items per request; use the pageNext cursor (returned in pages.next) to paginate.",
|
|
7449
|
+
inputParams: ListExperiencesToolParams.shape,
|
|
7450
|
+
annotations: {
|
|
7451
|
+
readOnlyHint: true,
|
|
7452
|
+
destructiveHint: false,
|
|
7453
|
+
openWorldHint: false
|
|
7454
|
+
},
|
|
7455
|
+
tool: listExperiences
|
|
7456
|
+
},
|
|
7457
|
+
createExperience: {
|
|
7458
|
+
title: "create_experience",
|
|
7459
|
+
description: "Create a new ExO experience backed by an ExperienceTemplate.",
|
|
7460
|
+
inputParams: CreateExperienceToolParams.shape,
|
|
7461
|
+
annotations: {
|
|
7462
|
+
readOnlyHint: false,
|
|
7463
|
+
destructiveHint: false,
|
|
7464
|
+
idempotentHint: false,
|
|
7465
|
+
openWorldHint: false
|
|
7466
|
+
},
|
|
7467
|
+
tool: createExperience
|
|
7468
|
+
},
|
|
7469
|
+
upsertExperience: {
|
|
7470
|
+
title: "upsert_experience",
|
|
7471
|
+
description: "Update an existing ExO experience. You MUST call get_experience first to read the current state, then pass the sys.version you received as the version parameter. The handler merges your updates with the existing experience fields, so you only need to provide the fields you want to change. If the version is stale (the experience changed since you read it), the update is rejected and you must re-fetch with get_experience.",
|
|
7472
|
+
inputParams: UpsertExperienceToolParams.shape,
|
|
7473
|
+
annotations: {
|
|
7474
|
+
readOnlyHint: false,
|
|
7475
|
+
destructiveHint: false,
|
|
7476
|
+
idempotentHint: false,
|
|
7477
|
+
openWorldHint: false
|
|
7478
|
+
},
|
|
7479
|
+
tool: upsertExperience
|
|
7480
|
+
},
|
|
7481
|
+
deleteExperience: {
|
|
7482
|
+
title: "delete_experience",
|
|
7483
|
+
description: "Delete an ExO experience. Two-phase: the first call (without confirm/confirmToken) returns a preview and a confirmToken. To complete the deletion, call again with the same experienceId, confirm: true, and the confirmToken from the preview.",
|
|
7484
|
+
inputParams: DeleteExperienceToolParams.shape,
|
|
7485
|
+
annotations: {
|
|
7486
|
+
readOnlyHint: false,
|
|
7487
|
+
destructiveHint: true,
|
|
7488
|
+
idempotentHint: false,
|
|
7489
|
+
openWorldHint: false
|
|
7490
|
+
},
|
|
7491
|
+
tool: deleteExperience
|
|
7492
|
+
},
|
|
7493
|
+
publishExperience: {
|
|
7494
|
+
title: "publish_experience",
|
|
7495
|
+
description: "Publish an ExO experience. You MUST call get_experience first and pass the returned sys.version as the version parameter. If the version is stale the operation is rejected and you must re-fetch with get_experience.",
|
|
7496
|
+
inputParams: PublishExperienceToolParams.shape,
|
|
7497
|
+
annotations: {
|
|
7498
|
+
readOnlyHint: false,
|
|
7499
|
+
destructiveHint: true,
|
|
7500
|
+
idempotentHint: true,
|
|
7501
|
+
openWorldHint: false
|
|
7502
|
+
},
|
|
7503
|
+
tool: publishExperience
|
|
7504
|
+
},
|
|
7505
|
+
unpublishExperience: {
|
|
7506
|
+
title: "unpublish_experience",
|
|
7507
|
+
description: "Unpublish an ExO experience. You MUST call get_experience first and pass the returned sys.version as the version parameter. If the version is stale the operation is rejected and you must re-fetch with get_experience.",
|
|
7508
|
+
inputParams: UnpublishExperienceToolParams.shape,
|
|
7509
|
+
annotations: {
|
|
7510
|
+
readOnlyHint: false,
|
|
7511
|
+
destructiveHint: true,
|
|
7512
|
+
idempotentHint: true,
|
|
7513
|
+
openWorldHint: false
|
|
7514
|
+
},
|
|
7515
|
+
tool: unpublishExperience
|
|
7516
|
+
}
|
|
7517
|
+
};
|
|
7518
|
+
}
|
|
7519
|
+
|
|
7520
|
+
// src/tools/exo/data-assemblies/getDataAssembly.ts
|
|
7521
|
+
import { z as z112 } from "zod";
|
|
7522
|
+
var GetDataAssemblyToolParams = BaseToolSchema.extend({
|
|
7523
|
+
dataAssemblyId: z112.string().describe("The ID of the data assembly to retrieve")
|
|
7524
|
+
});
|
|
7525
|
+
function getDataAssemblyTool(config) {
|
|
7526
|
+
async function tool2(args) {
|
|
7527
|
+
const contentfulClient = createToolClient(config, args);
|
|
7528
|
+
const dataAssembly = await contentfulClient.dataAssembly.get({
|
|
7529
|
+
spaceId: args.spaceId,
|
|
7530
|
+
environmentId: args.environmentId,
|
|
7531
|
+
dataAssemblyId: args.dataAssemblyId
|
|
7532
|
+
});
|
|
7533
|
+
return createSuccessResponse("Data assembly retrieved successfully", {
|
|
7534
|
+
dataAssembly
|
|
7535
|
+
});
|
|
7536
|
+
}
|
|
7537
|
+
return withErrorHandling(tool2, "Error retrieving data assembly");
|
|
7538
|
+
}
|
|
7539
|
+
|
|
7540
|
+
// src/tools/exo/data-assemblies/getPublishedDataAssembly.ts
|
|
7541
|
+
import { z as z113 } from "zod";
|
|
7542
|
+
var GetPublishedDataAssemblyToolParams = BaseToolSchema.extend({
|
|
7543
|
+
dataAssemblyId: z113.string().describe("The ID of the published data assembly to retrieve")
|
|
7544
|
+
});
|
|
7545
|
+
function getPublishedDataAssemblyTool(config) {
|
|
7546
|
+
async function tool2(args) {
|
|
7547
|
+
const contentfulClient = createToolClient(config, args);
|
|
7548
|
+
const dataAssembly = await contentfulClient.dataAssembly.getPublished({
|
|
7549
|
+
spaceId: args.spaceId,
|
|
7550
|
+
environmentId: args.environmentId,
|
|
7551
|
+
dataAssemblyId: args.dataAssemblyId
|
|
7552
|
+
});
|
|
7553
|
+
return createSuccessResponse("Published data assembly retrieved successfully", {
|
|
7554
|
+
dataAssembly
|
|
7555
|
+
});
|
|
7556
|
+
}
|
|
7557
|
+
return withErrorHandling(tool2, "Error retrieving published data assembly");
|
|
7558
|
+
}
|
|
7559
|
+
|
|
7560
|
+
// src/tools/exo/data-assemblies/listDataAssemblies.ts
|
|
7561
|
+
import { z as z114 } from "zod";
|
|
7562
|
+
var ListDataAssembliesToolParams = BaseToolSchema.extend({
|
|
7563
|
+
limit: z114.number().optional().describe("Maximum number of data assemblies to return (max 10)"),
|
|
7564
|
+
pageNext: z114.string().optional().describe("Cursor token to fetch the next page of results"),
|
|
7565
|
+
pagePrev: z114.string().optional().describe("Cursor token to fetch the previous page of results"),
|
|
7566
|
+
sysIdIn: z114.string().optional().describe("Comma-separated list of data assembly IDs to filter by")
|
|
7567
|
+
});
|
|
7568
|
+
function listDataAssembliesTool(config) {
|
|
7569
|
+
async function tool2(args) {
|
|
7570
|
+
const contentfulClient = createToolClient(config, args);
|
|
7571
|
+
const dataAssemblies = await contentfulClient.dataAssembly.getMany({
|
|
7572
|
+
spaceId: args.spaceId,
|
|
7573
|
+
environmentId: args.environmentId,
|
|
7574
|
+
query: {
|
|
7575
|
+
limit: Math.min(args.limit || 10, 10),
|
|
7576
|
+
...args.pageNext && { pageNext: args.pageNext },
|
|
7577
|
+
...args.pagePrev && { pagePrev: args.pagePrev },
|
|
7578
|
+
...args.sysIdIn && { "sys.id[in]": args.sysIdIn }
|
|
7579
|
+
}
|
|
7580
|
+
});
|
|
7581
|
+
const summarized = summarizeData(dataAssemblies, {
|
|
7582
|
+
maxItems: 10,
|
|
7583
|
+
remainingMessage: "To see more data assemblies, ask me to retrieve the next page using the pageNext cursor."
|
|
7584
|
+
});
|
|
7585
|
+
return createSuccessResponse("Data assemblies retrieved successfully", {
|
|
7586
|
+
dataAssemblies: summarized,
|
|
7587
|
+
total: dataAssemblies.total,
|
|
7588
|
+
pages: dataAssemblies.pages
|
|
7589
|
+
});
|
|
7590
|
+
}
|
|
7591
|
+
return withErrorHandling(tool2, "Error listing data assemblies");
|
|
7592
|
+
}
|
|
7593
|
+
|
|
7594
|
+
// src/tools/exo/data-assemblies/listPublishedDataAssemblies.ts
|
|
7595
|
+
import { z as z115 } from "zod";
|
|
7596
|
+
var ListPublishedDataAssembliesToolParams = BaseToolSchema.extend({
|
|
7597
|
+
limit: z115.number().optional().describe("Maximum number of published data assemblies to return (max 10)"),
|
|
7598
|
+
pageNext: z115.string().optional().describe("Cursor token to fetch the next page of results"),
|
|
7599
|
+
pagePrev: z115.string().optional().describe("Cursor token to fetch the previous page of results"),
|
|
7600
|
+
sysIdIn: z115.string().optional().describe("Comma-separated list of data assembly IDs to filter by")
|
|
7601
|
+
});
|
|
7602
|
+
function listPublishedDataAssembliesTool(config) {
|
|
7603
|
+
async function tool2(args) {
|
|
7604
|
+
const contentfulClient = createToolClient(config, args);
|
|
7605
|
+
const dataAssemblies = await contentfulClient.dataAssembly.getManyPublished({
|
|
7606
|
+
spaceId: args.spaceId,
|
|
7607
|
+
environmentId: args.environmentId,
|
|
7608
|
+
query: {
|
|
7609
|
+
limit: Math.min(args.limit || 10, 10),
|
|
7610
|
+
...args.pageNext && { pageNext: args.pageNext },
|
|
7611
|
+
...args.pagePrev && { pagePrev: args.pagePrev },
|
|
7612
|
+
...args.sysIdIn && { "sys.id[in]": args.sysIdIn }
|
|
7613
|
+
}
|
|
7614
|
+
});
|
|
7615
|
+
const summarized = summarizeData(dataAssemblies, {
|
|
7616
|
+
maxItems: 10,
|
|
7617
|
+
remainingMessage: "To see more published data assemblies, ask me to retrieve the next page using the pageNext cursor."
|
|
7618
|
+
});
|
|
7619
|
+
return createSuccessResponse("Published data assemblies retrieved successfully", {
|
|
7620
|
+
dataAssemblies: summarized,
|
|
7621
|
+
total: dataAssemblies.total,
|
|
7622
|
+
pages: dataAssemblies.pages
|
|
7623
|
+
});
|
|
7624
|
+
}
|
|
7625
|
+
return withErrorHandling(tool2, "Error listing published data assemblies");
|
|
7626
|
+
}
|
|
7627
|
+
|
|
7628
|
+
// src/tools/exo/data-assemblies/createDataAssembly.ts
|
|
7629
|
+
import { z as z117 } from "zod";
|
|
7630
|
+
|
|
7631
|
+
// src/types/dataAssemblySchemas.ts
|
|
7632
|
+
import { z as z116 } from "zod";
|
|
7633
|
+
var PointerExpressionValueSchema = z116.lazy(
|
|
7634
|
+
() => z116.union([
|
|
7635
|
+
z116.string(),
|
|
7636
|
+
z116.object({
|
|
7637
|
+
$from: z116.union([
|
|
7638
|
+
z116.string(),
|
|
7639
|
+
z116.object({
|
|
7640
|
+
source: z116.string(),
|
|
7641
|
+
select: PointerExpressionValueSchema.optional()
|
|
7642
|
+
})
|
|
7643
|
+
])
|
|
7644
|
+
}),
|
|
7645
|
+
z116.object({ $literal: z116.custom() }),
|
|
7646
|
+
z116.object({ $object: z116.record(z116.string(), PointerExpressionValueSchema) }),
|
|
7647
|
+
z116.object({
|
|
7648
|
+
$on: z116.object({
|
|
7649
|
+
type: z116.record(z116.string(), PointerExpressionValueSchema),
|
|
7650
|
+
default: PointerExpressionValueSchema.optional()
|
|
7651
|
+
})
|
|
7652
|
+
}),
|
|
7653
|
+
z116.record(z116.string(), PointerExpressionValueSchema)
|
|
7654
|
+
])
|
|
7655
|
+
);
|
|
7656
|
+
var CanonicalDataTypeArmSchema = z116.object({
|
|
7657
|
+
type: z116.enum([
|
|
7658
|
+
"String",
|
|
7659
|
+
"Number",
|
|
7660
|
+
"Integer",
|
|
7661
|
+
"Boolean",
|
|
7662
|
+
"RichText",
|
|
7663
|
+
"Array",
|
|
7664
|
+
"Record",
|
|
7665
|
+
"TypeRef",
|
|
7666
|
+
"Literal",
|
|
7667
|
+
"DiscriminatedUnion"
|
|
7668
|
+
]),
|
|
7669
|
+
id: z116.string().describe("Data type field identifier"),
|
|
7670
|
+
name: z116.string().describe("Human-readable name"),
|
|
7671
|
+
required: z116.boolean().optional()
|
|
7672
|
+
}).catchall(z116.unknown());
|
|
7673
|
+
var LegacyDataTypeArmSchema = z116.object({
|
|
7674
|
+
id: z116.string().describe("Data type field identifier"),
|
|
7675
|
+
name: z116.string().describe("Human-readable name"),
|
|
7676
|
+
type: z116.string(),
|
|
7677
|
+
required: z116.boolean().optional(),
|
|
7678
|
+
source: z116.string().optional(),
|
|
7679
|
+
ref: z116.unknown().optional()
|
|
7680
|
+
});
|
|
7681
|
+
var DataAssemblyDataTypeFieldSchema = z116.union([
|
|
7682
|
+
CanonicalDataTypeArmSchema,
|
|
7683
|
+
LegacyDataTypeArmSchema
|
|
7684
|
+
]);
|
|
7685
|
+
var SAME_SPACE_CONTENT_SOURCE = "crn:contentful:::content:spaces/$self/environments/$self";
|
|
7686
|
+
var DataAssemblyResourceLinkParameterSchema = z116.object({
|
|
7687
|
+
name: z116.string().optional(),
|
|
7688
|
+
description: z116.string().optional(),
|
|
7689
|
+
type: z116.literal("ResourceLink"),
|
|
7690
|
+
linkType: z116.literal("Contentful:Entry"),
|
|
7691
|
+
allowedResources: z116.array(
|
|
7692
|
+
z116.object({
|
|
7693
|
+
type: z116.literal("Contentful:Entry"),
|
|
7694
|
+
source: z116.literal(SAME_SPACE_CONTENT_SOURCE),
|
|
7695
|
+
allowedTypes: z116.array(z116.string())
|
|
7696
|
+
})
|
|
7697
|
+
)
|
|
7698
|
+
});
|
|
7699
|
+
var DataAssemblyParameterConfigSchema = z116.record(
|
|
7700
|
+
z116.string(),
|
|
7701
|
+
DataAssemblyResourceLinkParameterSchema
|
|
7702
|
+
);
|
|
7703
|
+
var DataAssemblyGraphQLResolverSchema = z116.object({
|
|
7704
|
+
source: z116.literal("Contentful:GraphQL"),
|
|
7705
|
+
query: z116.string().describe("GraphQL query string"),
|
|
7706
|
+
parameters: PointerExpressionValueSchema.optional()
|
|
7707
|
+
});
|
|
7708
|
+
var DataAssemblyNestedResolverSchema = z116.object({
|
|
7709
|
+
source: z116.literal("Contentful:DataAssembly"),
|
|
7710
|
+
dataAssembly: z116.object({
|
|
7711
|
+
sys: z116.object({
|
|
7712
|
+
type: z116.literal("ResourceLink"),
|
|
7713
|
+
linkType: z116.literal("Contentful:DataAssembly"),
|
|
7714
|
+
urn: z116.string()
|
|
7715
|
+
})
|
|
7716
|
+
}),
|
|
7717
|
+
parameters: PointerExpressionValueSchema.optional()
|
|
7718
|
+
});
|
|
7719
|
+
var DataAssemblyResolverDefinitionSchema = z116.union([
|
|
7720
|
+
DataAssemblyGraphQLResolverSchema,
|
|
7721
|
+
DataAssemblyNestedResolverSchema
|
|
7722
|
+
]);
|
|
7723
|
+
var DataAssemblyResolverConfigSchema = z116.record(
|
|
7724
|
+
z116.string(),
|
|
7725
|
+
DataAssemblyResolverDefinitionSchema
|
|
7726
|
+
);
|
|
7727
|
+
var DataAssemblyReturnMappingConfigSchema = PointerExpressionValueSchema;
|
|
7728
|
+
var DataAssemblyMetadataSchema = z116.object({
|
|
7729
|
+
tags: z116.array(
|
|
7730
|
+
z116.object({
|
|
7731
|
+
sys: z116.object({
|
|
7732
|
+
type: z116.literal("Link"),
|
|
7733
|
+
linkType: z116.literal("Tag"),
|
|
7734
|
+
id: z116.string()
|
|
7735
|
+
})
|
|
7736
|
+
})
|
|
7737
|
+
)
|
|
7738
|
+
});
|
|
7739
|
+
|
|
7740
|
+
// src/tools/exo/data-assemblies/createDataAssembly.ts
|
|
7741
|
+
var CreateDataAssemblyToolParams = BaseToolSchema.extend({
|
|
7742
|
+
name: z117.string().describe("The name of the data assembly"),
|
|
7743
|
+
description: z117.string().describe("Description of the data assembly"),
|
|
7744
|
+
parameters: DataAssemblyParameterConfigSchema.describe(
|
|
7745
|
+
"Parameter definitions keyed by parameter name (may be empty object)"
|
|
7746
|
+
),
|
|
7747
|
+
resolvers: DataAssemblyResolverConfigSchema.describe(
|
|
7748
|
+
"Resolver definitions keyed by resolver name (may be empty object)"
|
|
7749
|
+
),
|
|
7750
|
+
return: DataAssemblyReturnMappingConfigSchema.describe(
|
|
7751
|
+
"Return mapping configuration specifying how to map resolved data"
|
|
7752
|
+
),
|
|
7753
|
+
dataType: z117.array(DataAssemblyDataTypeFieldSchema).describe("Data type field definitions for this data assembly (may be empty array)"),
|
|
7754
|
+
variant: z117.string().optional().describe("Optional variant identifier for this data assembly"),
|
|
7755
|
+
metadata: DataAssemblyMetadataSchema.optional().describe("Optional metadata (tags)")
|
|
7756
|
+
});
|
|
7757
|
+
function createDataAssemblyTool(config) {
|
|
7758
|
+
async function tool2(args) {
|
|
7759
|
+
assertEnvironmentNotProtected(
|
|
7760
|
+
args.environmentId,
|
|
7761
|
+
config.protectedEnvironments
|
|
7762
|
+
);
|
|
7763
|
+
const contentfulClient = createToolClient(config, args);
|
|
7764
|
+
const dataAssembly = await contentfulClient.dataAssembly.create(
|
|
7765
|
+
{ spaceId: args.spaceId, environmentId: args.environmentId },
|
|
7766
|
+
{
|
|
7767
|
+
sys: {
|
|
7768
|
+
type: "DataAssembly",
|
|
7769
|
+
dataType: args.dataType,
|
|
7770
|
+
...args.variant && { variant: args.variant }
|
|
7771
|
+
},
|
|
7772
|
+
name: args.name,
|
|
7773
|
+
description: args.description,
|
|
7774
|
+
parameters: args.parameters,
|
|
7775
|
+
resolvers: args.resolvers,
|
|
7776
|
+
return: args.return,
|
|
7777
|
+
metadata: args.metadata ?? { tags: [] }
|
|
7778
|
+
}
|
|
7779
|
+
);
|
|
7780
|
+
return createSuccessResponse("Data assembly created successfully", {
|
|
7781
|
+
dataAssembly
|
|
7782
|
+
});
|
|
7783
|
+
}
|
|
7784
|
+
return withErrorHandling(tool2, "Error creating data assembly");
|
|
7785
|
+
}
|
|
7786
|
+
|
|
7787
|
+
// src/tools/exo/data-assemblies/updateDataAssembly.ts
|
|
7788
|
+
import { z as z118 } from "zod";
|
|
7789
|
+
var UpdateDataAssemblyToolParams = BaseToolSchema.extend({
|
|
7790
|
+
dataAssemblyId: z118.string().describe("The ID of the data assembly to update"),
|
|
7791
|
+
version: z118.number().describe(
|
|
7792
|
+
"REQUIRED. The data assembly's sys.version as returned by get_data_assembly. You must call get_data_assembly first to read the current state and version. The update is rejected if this does not match the current version, which means the data assembly changed since you read it."
|
|
7793
|
+
),
|
|
7794
|
+
name: z118.string().optional().describe("The name of the data assembly"),
|
|
7795
|
+
description: z118.string().optional().describe("Description of the data assembly"),
|
|
7796
|
+
parameters: DataAssemblyParameterConfigSchema.optional().describe(
|
|
7797
|
+
"Parameter definitions; replaces existing if provided"
|
|
7798
|
+
),
|
|
7799
|
+
resolvers: DataAssemblyResolverConfigSchema.optional().describe(
|
|
7800
|
+
"Resolver definitions; replaces existing if provided"
|
|
7801
|
+
),
|
|
7802
|
+
return: DataAssemblyReturnMappingConfigSchema.optional().describe(
|
|
7803
|
+
"Return mapping configuration; replaces existing if provided"
|
|
7804
|
+
),
|
|
7805
|
+
dataType: z118.array(DataAssemblyDataTypeFieldSchema).optional().describe("Data type field definitions; replaces existing if provided"),
|
|
7806
|
+
variant: z118.string().optional().describe("Optional variant identifier; replaces existing if provided"),
|
|
7807
|
+
metadata: DataAssemblyMetadataSchema.optional().describe(
|
|
7808
|
+
"Metadata (tags); replaces existing if provided"
|
|
7809
|
+
)
|
|
7810
|
+
});
|
|
7811
|
+
function updateDataAssemblyTool(config) {
|
|
7812
|
+
async function tool2(args) {
|
|
7813
|
+
assertEnvironmentNotProtected(
|
|
7814
|
+
args.environmentId,
|
|
7815
|
+
config.protectedEnvironments
|
|
7816
|
+
);
|
|
7817
|
+
const params = {
|
|
7818
|
+
spaceId: args.spaceId,
|
|
7819
|
+
environmentId: args.environmentId,
|
|
7820
|
+
dataAssemblyId: args.dataAssemblyId
|
|
7821
|
+
};
|
|
7822
|
+
const contentfulClient = createToolClient(config, args);
|
|
7823
|
+
const current = await contentfulClient.dataAssembly.get(params);
|
|
7824
|
+
if (args.version !== current.sys.version) {
|
|
7825
|
+
throw new Error(
|
|
7826
|
+
`Version conflict: the data assembly has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the data assembly with get_data_assembly and retry the update with the latest sys.version.`
|
|
7827
|
+
);
|
|
7828
|
+
}
|
|
7829
|
+
const dataAssembly = await contentfulClient.dataAssembly.update(params, {
|
|
7830
|
+
sys: {
|
|
7831
|
+
id: current.sys.id,
|
|
7832
|
+
type: "DataAssembly",
|
|
7833
|
+
version: current.sys.version,
|
|
7834
|
+
dataType: args.dataType ?? current.sys.dataType,
|
|
7835
|
+
...args.variant !== void 0 ? { variant: args.variant } : current.sys.variant !== void 0 ? { variant: current.sys.variant } : {}
|
|
7836
|
+
},
|
|
7837
|
+
name: args.name ?? current.name,
|
|
7838
|
+
description: args.description ?? current.description,
|
|
7839
|
+
parameters: args.parameters ?? current.parameters,
|
|
7840
|
+
resolvers: args.resolvers ?? current.resolvers,
|
|
7841
|
+
return: args.return ?? current.return,
|
|
7842
|
+
metadata: args.metadata ?? current.metadata
|
|
7843
|
+
});
|
|
7844
|
+
return createSuccessResponse("Data assembly updated successfully", {
|
|
7845
|
+
dataAssembly
|
|
7846
|
+
});
|
|
7847
|
+
}
|
|
7848
|
+
return withErrorHandling(tool2, "Error updating data assembly");
|
|
7849
|
+
}
|
|
7850
|
+
|
|
7851
|
+
// src/tools/exo/data-assemblies/deleteDataAssembly.ts
|
|
7852
|
+
import { z as z119 } from "zod";
|
|
7853
|
+
var DeleteDataAssemblyToolParams = BaseToolSchema.extend({
|
|
7854
|
+
dataAssemblyId: z119.string().describe("The ID of the data assembly to delete"),
|
|
7855
|
+
confirm: z119.boolean().optional().describe(
|
|
7856
|
+
"Set to true on the second call to actually perform the deletion. Required together with confirmToken."
|
|
7857
|
+
),
|
|
7858
|
+
confirmToken: z119.string().optional().describe(
|
|
7859
|
+
"Token returned by the preview call; must be supplied with confirm: true."
|
|
7860
|
+
)
|
|
7861
|
+
});
|
|
7862
|
+
function deleteDataAssemblyTool(config) {
|
|
7863
|
+
async function tool2(args) {
|
|
7864
|
+
assertEnvironmentNotProtected(
|
|
7865
|
+
args.environmentId,
|
|
7866
|
+
config.protectedEnvironments
|
|
7867
|
+
);
|
|
7868
|
+
const params = {
|
|
7869
|
+
spaceId: args.spaceId,
|
|
7870
|
+
environmentId: args.environmentId,
|
|
7871
|
+
dataAssemblyId: args.dataAssemblyId
|
|
7872
|
+
};
|
|
7873
|
+
const contentfulClient = createToolClient(config, args);
|
|
7874
|
+
const dataAssembly = await contentfulClient.dataAssembly.get(params);
|
|
7875
|
+
const expectedToken = buildConfirmToken(
|
|
7876
|
+
"dataAssembly",
|
|
7877
|
+
args.dataAssemblyId,
|
|
7878
|
+
dataAssembly.sys.version
|
|
7879
|
+
);
|
|
7880
|
+
if (args.confirm !== true || args.confirmToken !== expectedToken) {
|
|
7881
|
+
return createSuccessResponse(
|
|
7882
|
+
`${CONFIRMATION_MESSAGE_PREFIX} data assembly`,
|
|
7883
|
+
buildConfirmationPreview(
|
|
7884
|
+
"dataAssembly",
|
|
7885
|
+
args.dataAssemblyId,
|
|
7886
|
+
{ dataAssembly },
|
|
7887
|
+
expectedToken
|
|
7888
|
+
)
|
|
7889
|
+
);
|
|
7890
|
+
}
|
|
7891
|
+
await contentfulClient.dataAssembly.delete(params);
|
|
7892
|
+
return createSuccessResponse("Data assembly deleted successfully", {
|
|
7893
|
+
dataAssemblyId: args.dataAssemblyId
|
|
7894
|
+
});
|
|
7895
|
+
}
|
|
7896
|
+
return withErrorHandling(tool2, "Error deleting data assembly");
|
|
7897
|
+
}
|
|
7898
|
+
|
|
7899
|
+
// src/tools/exo/data-assemblies/publishDataAssembly.ts
|
|
7900
|
+
import { z as z120 } from "zod";
|
|
7901
|
+
var PublishDataAssemblyToolParams = BaseToolSchema.extend({
|
|
7902
|
+
dataAssemblyId: z120.string().describe("The ID of the data assembly to publish"),
|
|
7903
|
+
version: z120.number().describe(
|
|
7904
|
+
"REQUIRED. The data assembly's sys.version as returned by get_data_assembly. You must call get_data_assembly first to read the current state and version. The publish is rejected if this does not match the current version, which means the data assembly changed since you read it."
|
|
7905
|
+
)
|
|
7906
|
+
});
|
|
7907
|
+
function publishDataAssemblyTool(config) {
|
|
7908
|
+
async function tool2(args) {
|
|
7909
|
+
assertEnvironmentNotProtected(
|
|
7910
|
+
args.environmentId,
|
|
7911
|
+
config.protectedEnvironments
|
|
7912
|
+
);
|
|
7913
|
+
const params = {
|
|
7914
|
+
spaceId: args.spaceId,
|
|
7915
|
+
environmentId: args.environmentId,
|
|
7916
|
+
dataAssemblyId: args.dataAssemblyId
|
|
7917
|
+
};
|
|
7918
|
+
const contentfulClient = createToolClient(config, args);
|
|
7919
|
+
const current = await contentfulClient.dataAssembly.get(params);
|
|
7920
|
+
if (args.version !== current.sys.version) {
|
|
7921
|
+
throw new Error(
|
|
7922
|
+
`Version conflict: the data assembly has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the data assembly with get_data_assembly and retry with the latest sys.version.`
|
|
7923
|
+
);
|
|
7924
|
+
}
|
|
7925
|
+
const dataAssembly = await contentfulClient.dataAssembly.publish({
|
|
7926
|
+
...params,
|
|
7927
|
+
version: args.version
|
|
7928
|
+
});
|
|
7929
|
+
return createSuccessResponse("Data assembly published successfully", {
|
|
7930
|
+
dataAssembly
|
|
7931
|
+
});
|
|
7932
|
+
}
|
|
7933
|
+
return withErrorHandling(tool2, "Error publishing data assembly");
|
|
7934
|
+
}
|
|
7935
|
+
|
|
7936
|
+
// src/tools/exo/data-assemblies/unpublishDataAssembly.ts
|
|
7937
|
+
import { z as z121 } from "zod";
|
|
7938
|
+
var UnpublishDataAssemblyToolParams = BaseToolSchema.extend({
|
|
7939
|
+
dataAssemblyId: z121.string().describe("The ID of the data assembly to unpublish"),
|
|
7940
|
+
version: z121.number().describe(
|
|
7941
|
+
"REQUIRED. The data assembly's sys.version as returned by get_data_assembly. You must call get_data_assembly first to read the current state and version. The unpublish is rejected if this does not match the current version, which means the data assembly changed since you read it."
|
|
7942
|
+
)
|
|
7943
|
+
});
|
|
7944
|
+
function unpublishDataAssemblyTool(config) {
|
|
7945
|
+
async function tool2(args) {
|
|
7946
|
+
assertEnvironmentNotProtected(
|
|
7947
|
+
args.environmentId,
|
|
7948
|
+
config.protectedEnvironments
|
|
7949
|
+
);
|
|
7950
|
+
const params = {
|
|
7951
|
+
spaceId: args.spaceId,
|
|
7952
|
+
environmentId: args.environmentId,
|
|
7953
|
+
dataAssemblyId: args.dataAssemblyId
|
|
7954
|
+
};
|
|
7955
|
+
const contentfulClient = createToolClient(config, args);
|
|
7956
|
+
const current = await contentfulClient.dataAssembly.get(params);
|
|
7957
|
+
if (args.version !== current.sys.version) {
|
|
7958
|
+
throw new Error(
|
|
7959
|
+
`Version conflict: the data assembly has changed since you read it (your version: ${args.version}, current version: ${current.sys.version}). Re-fetch the data assembly with get_data_assembly and retry with the latest sys.version.`
|
|
7960
|
+
);
|
|
7961
|
+
}
|
|
7962
|
+
const dataAssembly = await contentfulClient.dataAssembly.unpublish({
|
|
7963
|
+
...params,
|
|
7964
|
+
version: args.version
|
|
7965
|
+
});
|
|
7966
|
+
return createSuccessResponse("Data assembly unpublished successfully", {
|
|
7967
|
+
dataAssembly
|
|
7968
|
+
});
|
|
7969
|
+
}
|
|
7970
|
+
return withErrorHandling(tool2, "Error unpublishing data assembly");
|
|
7971
|
+
}
|
|
7972
|
+
|
|
7973
|
+
// src/tools/exo/data-assemblies/register.ts
|
|
7974
|
+
function createDataAssemblyTools(config) {
|
|
7975
|
+
const getDataAssembly = getDataAssemblyTool(config);
|
|
7976
|
+
const getPublishedDataAssembly = getPublishedDataAssemblyTool(config);
|
|
7977
|
+
const listDataAssemblies = listDataAssembliesTool(config);
|
|
7978
|
+
const listPublishedDataAssemblies = listPublishedDataAssembliesTool(config);
|
|
7979
|
+
const createDataAssembly = createDataAssemblyTool(config);
|
|
7980
|
+
const updateDataAssembly = updateDataAssemblyTool(config);
|
|
7981
|
+
const deleteDataAssembly = deleteDataAssemblyTool(config);
|
|
7982
|
+
const publishDataAssembly = publishDataAssemblyTool(config);
|
|
7983
|
+
const unpublishDataAssembly = unpublishDataAssemblyTool(config);
|
|
7984
|
+
return {
|
|
7985
|
+
getDataAssembly: {
|
|
7986
|
+
title: "get_data_assembly",
|
|
7987
|
+
description: "Get details about a specific ExO DataAssembly (a smart data recipe that specifies how to fetch and reshape data for a component or page in a single operation).",
|
|
7988
|
+
inputParams: GetDataAssemblyToolParams.shape,
|
|
7989
|
+
annotations: {
|
|
7990
|
+
readOnlyHint: true,
|
|
7991
|
+
destructiveHint: false,
|
|
7992
|
+
openWorldHint: false
|
|
7993
|
+
},
|
|
7994
|
+
tool: getDataAssembly
|
|
7995
|
+
},
|
|
7996
|
+
getPublishedDataAssembly: {
|
|
7997
|
+
title: "get_published_data_assembly",
|
|
7998
|
+
description: "Get details about a specific published ExO DataAssembly by ID.",
|
|
7999
|
+
inputParams: GetPublishedDataAssemblyToolParams.shape,
|
|
8000
|
+
annotations: {
|
|
8001
|
+
readOnlyHint: true,
|
|
8002
|
+
destructiveHint: false,
|
|
8003
|
+
openWorldHint: false
|
|
8004
|
+
},
|
|
8005
|
+
tool: getPublishedDataAssembly
|
|
8006
|
+
},
|
|
8007
|
+
listDataAssemblies: {
|
|
8008
|
+
title: "list_data_assemblies",
|
|
8009
|
+
description: "List ExO DataAssemblies in a space and environment. Returns a maximum of 10 items per request; use the pageNext cursor (returned in pages.next) to paginate.",
|
|
8010
|
+
inputParams: ListDataAssembliesToolParams.shape,
|
|
8011
|
+
annotations: {
|
|
8012
|
+
readOnlyHint: true,
|
|
8013
|
+
destructiveHint: false,
|
|
8014
|
+
openWorldHint: false
|
|
8015
|
+
},
|
|
8016
|
+
tool: listDataAssemblies
|
|
8017
|
+
},
|
|
8018
|
+
listPublishedDataAssemblies: {
|
|
8019
|
+
title: "list_published_data_assemblies",
|
|
8020
|
+
description: "List published ExO DataAssemblies in a space and environment. Returns a maximum of 10 items per request; use the pageNext cursor (returned in pages.next) to paginate.",
|
|
8021
|
+
inputParams: ListPublishedDataAssembliesToolParams.shape,
|
|
8022
|
+
annotations: {
|
|
8023
|
+
readOnlyHint: true,
|
|
8024
|
+
destructiveHint: false,
|
|
8025
|
+
openWorldHint: false
|
|
8026
|
+
},
|
|
8027
|
+
tool: listPublishedDataAssemblies
|
|
8028
|
+
},
|
|
8029
|
+
createDataAssembly: {
|
|
8030
|
+
title: "create_data_assembly",
|
|
8031
|
+
description: "Create a new ExO DataAssembly.",
|
|
8032
|
+
inputParams: CreateDataAssemblyToolParams.shape,
|
|
8033
|
+
annotations: {
|
|
8034
|
+
readOnlyHint: false,
|
|
8035
|
+
destructiveHint: false,
|
|
8036
|
+
idempotentHint: false,
|
|
8037
|
+
openWorldHint: false
|
|
8038
|
+
},
|
|
8039
|
+
tool: createDataAssembly
|
|
8040
|
+
},
|
|
8041
|
+
updateDataAssembly: {
|
|
8042
|
+
title: "update_data_assembly",
|
|
8043
|
+
description: "Update an existing ExO DataAssembly. You MUST call get_data_assembly first to read the current state, then pass the sys.version you received as the version parameter. The handler merges your updates with the existing data assembly fields, so you only need to provide the fields you want to change. If the version is stale (the data assembly changed since you read it), the update is rejected and you must re-fetch with get_data_assembly.",
|
|
8044
|
+
inputParams: UpdateDataAssemblyToolParams.shape,
|
|
8045
|
+
annotations: {
|
|
8046
|
+
readOnlyHint: false,
|
|
8047
|
+
destructiveHint: false,
|
|
8048
|
+
idempotentHint: false,
|
|
8049
|
+
openWorldHint: false
|
|
8050
|
+
},
|
|
8051
|
+
tool: updateDataAssembly
|
|
8052
|
+
},
|
|
8053
|
+
deleteDataAssembly: {
|
|
8054
|
+
title: "delete_data_assembly",
|
|
8055
|
+
description: "Delete an ExO DataAssembly. Two-phase: the first call (without confirm/confirmToken) returns a preview and a confirmToken. To complete the deletion, call again with the same dataAssemblyId, confirm: true, and the confirmToken from the preview.",
|
|
8056
|
+
inputParams: DeleteDataAssemblyToolParams.shape,
|
|
8057
|
+
annotations: {
|
|
8058
|
+
readOnlyHint: false,
|
|
8059
|
+
destructiveHint: true,
|
|
8060
|
+
idempotentHint: false,
|
|
8061
|
+
openWorldHint: false
|
|
8062
|
+
},
|
|
8063
|
+
tool: deleteDataAssembly
|
|
8064
|
+
},
|
|
8065
|
+
publishDataAssembly: {
|
|
8066
|
+
title: "publish_data_assembly",
|
|
8067
|
+
description: "Publish an ExO DataAssembly. You MUST call get_data_assembly first and pass the returned sys.version as the version parameter. If the version is stale the operation is rejected and you must re-fetch with get_data_assembly.",
|
|
8068
|
+
inputParams: PublishDataAssemblyToolParams.shape,
|
|
8069
|
+
annotations: {
|
|
8070
|
+
readOnlyHint: false,
|
|
8071
|
+
destructiveHint: true,
|
|
8072
|
+
idempotentHint: true,
|
|
8073
|
+
openWorldHint: false
|
|
8074
|
+
},
|
|
8075
|
+
tool: publishDataAssembly
|
|
8076
|
+
},
|
|
8077
|
+
unpublishDataAssembly: {
|
|
8078
|
+
title: "unpublish_data_assembly",
|
|
8079
|
+
description: "Unpublish an ExO DataAssembly. You MUST call get_data_assembly first and pass the returned sys.version as the version parameter. If the version is stale the operation is rejected and you must re-fetch with get_data_assembly.",
|
|
8080
|
+
inputParams: UnpublishDataAssemblyToolParams.shape,
|
|
8081
|
+
annotations: {
|
|
8082
|
+
readOnlyHint: false,
|
|
8083
|
+
destructiveHint: true,
|
|
8084
|
+
idempotentHint: true,
|
|
8085
|
+
openWorldHint: false
|
|
8086
|
+
},
|
|
8087
|
+
tool: unpublishDataAssembly
|
|
8088
|
+
}
|
|
8089
|
+
};
|
|
8090
|
+
}
|
|
8091
|
+
|
|
8092
|
+
// src/ContentfulMcpTools.ts
|
|
8093
|
+
var ContentfulMcpTools = class {
|
|
8094
|
+
config;
|
|
8095
|
+
constructor(config) {
|
|
8096
|
+
this.config = {
|
|
8097
|
+
...config,
|
|
8098
|
+
host: config.host ?? "api.contentful.com",
|
|
8099
|
+
environmentId: config.environmentId ?? "master"
|
|
8100
|
+
};
|
|
8101
|
+
}
|
|
8102
|
+
/**
|
|
8103
|
+
* Update the configuration after initialization
|
|
8104
|
+
*
|
|
8105
|
+
* @param updates - Partial configuration to merge with existing config
|
|
8106
|
+
*/
|
|
8107
|
+
updateConfig(updates) {
|
|
8108
|
+
this.config = { ...this.config, ...updates };
|
|
8109
|
+
}
|
|
8110
|
+
/**
|
|
8111
|
+
* Get AI action tools
|
|
8112
|
+
*/
|
|
8113
|
+
getAiActionTools() {
|
|
8114
|
+
return createAiActionTools(this.config);
|
|
8115
|
+
}
|
|
8116
|
+
/**
|
|
8117
|
+
* Get asset tools
|
|
8118
|
+
*/
|
|
8119
|
+
getAssetTools() {
|
|
8120
|
+
return createAssetTools(this.config);
|
|
8121
|
+
}
|
|
8122
|
+
/**
|
|
8123
|
+
* Get content type tools
|
|
8124
|
+
*/
|
|
8125
|
+
getContentTypeTools() {
|
|
8126
|
+
return createContentTypeTools(this.config);
|
|
8127
|
+
}
|
|
8128
|
+
/**
|
|
8129
|
+
* Get ExO component tools
|
|
8130
|
+
*/
|
|
8131
|
+
getComponentTools() {
|
|
8132
|
+
return createComponentTools(this.config);
|
|
8133
|
+
}
|
|
8134
|
+
/**
|
|
8135
|
+
* Get ExO experience template tools
|
|
8136
|
+
*/
|
|
8137
|
+
getExperienceTemplateTools() {
|
|
8138
|
+
return createExperienceTemplateTools(this.config);
|
|
8139
|
+
}
|
|
8140
|
+
/**
|
|
8141
|
+
* Get ExO experience tools
|
|
8142
|
+
*/
|
|
8143
|
+
getExperienceTools() {
|
|
8144
|
+
return createExperienceTools(this.config);
|
|
8145
|
+
}
|
|
8146
|
+
/**
|
|
8147
|
+
* Get context tools
|
|
8148
|
+
*/
|
|
8149
|
+
getContextTools() {
|
|
8150
|
+
return createContextTools(this.config);
|
|
8151
|
+
}
|
|
8152
|
+
/**
|
|
8153
|
+
* Get editor interface tools
|
|
8154
|
+
*/
|
|
8155
|
+
getEditorInterfaceTools() {
|
|
8156
|
+
return createEditorInterfaceTools(this.config);
|
|
8157
|
+
}
|
|
8158
|
+
/**
|
|
8159
|
+
* Get entry tools
|
|
8160
|
+
*/
|
|
8161
|
+
getEntryTools() {
|
|
8162
|
+
return createEntryTools(this.config);
|
|
8163
|
+
}
|
|
8164
|
+
/**
|
|
8165
|
+
* Get environment tools
|
|
8166
|
+
*/
|
|
8167
|
+
getEnvironmentTools() {
|
|
8168
|
+
return createEnvironmentTools(this.config);
|
|
8169
|
+
}
|
|
8170
|
+
/**
|
|
8171
|
+
* Get locale tools
|
|
8172
|
+
*/
|
|
8173
|
+
getLocaleTools() {
|
|
8174
|
+
return createLocaleTools(this.config);
|
|
8175
|
+
}
|
|
8176
|
+
/**
|
|
8177
|
+
* Get organization tools
|
|
8178
|
+
*/
|
|
8179
|
+
getOrgTools() {
|
|
8180
|
+
return createOrgTools(this.config);
|
|
8181
|
+
}
|
|
8182
|
+
/**
|
|
8183
|
+
* Get space tools
|
|
8184
|
+
*/
|
|
8185
|
+
getSpaceTools() {
|
|
8186
|
+
return createSpaceTools(this.config);
|
|
8187
|
+
}
|
|
8188
|
+
/**
|
|
5868
8189
|
* Get tag tools
|
|
5869
8190
|
*/
|
|
5870
8191
|
getTagTools() {
|
|
@@ -5876,6 +8197,18 @@ var ContentfulMcpTools = class {
|
|
|
5876
8197
|
getTaxonomyTools() {
|
|
5877
8198
|
return createTaxonomyTools(this.config);
|
|
5878
8199
|
}
|
|
8200
|
+
/**
|
|
8201
|
+
* Get ExO experience fragment tools
|
|
8202
|
+
*/
|
|
8203
|
+
getExperienceFragmentTools() {
|
|
8204
|
+
return createExperienceFragmentTools(this.config);
|
|
8205
|
+
}
|
|
8206
|
+
/**
|
|
8207
|
+
* Get ExO data assembly tools
|
|
8208
|
+
*/
|
|
8209
|
+
getDataAssemblyTools() {
|
|
8210
|
+
return createDataAssemblyTools(this.config);
|
|
8211
|
+
}
|
|
5879
8212
|
/**
|
|
5880
8213
|
* Get job tools (space-to-space migration)
|
|
5881
8214
|
*/
|
|
@@ -5883,6 +8216,44 @@ var ContentfulMcpTools = class {
|
|
|
5883
8216
|
return createJobTools(this.config);
|
|
5884
8217
|
}
|
|
5885
8218
|
};
|
|
8219
|
+
|
|
8220
|
+
// src/utils/entitlements.ts
|
|
8221
|
+
import { createClient as createClient16 } from "contentful-management";
|
|
8222
|
+
var EXO_M1_FEATURE = "exoM1";
|
|
8223
|
+
function createPlainClient(config) {
|
|
8224
|
+
return createClient16(createClientConfig(config), { type: "plain" });
|
|
8225
|
+
}
|
|
8226
|
+
async function orgHasExoM1(client, organizationId) {
|
|
8227
|
+
try {
|
|
8228
|
+
const entitlements = await client.raw.get(
|
|
8229
|
+
`/organizations/${organizationId}/organization_entitlement_set`
|
|
8230
|
+
);
|
|
8231
|
+
return entitlements.features?.[EXO_M1_FEATURE]?.value === true;
|
|
8232
|
+
} catch {
|
|
8233
|
+
return false;
|
|
8234
|
+
}
|
|
8235
|
+
}
|
|
8236
|
+
async function hasExoM1Entitlement(config) {
|
|
8237
|
+
try {
|
|
8238
|
+
const client = createPlainClient(config);
|
|
8239
|
+
const orgs = await client.organization.getAll();
|
|
8240
|
+
if (!orgs.items.length) {
|
|
8241
|
+
return false;
|
|
8242
|
+
}
|
|
8243
|
+
const results = await Promise.all(
|
|
8244
|
+
orgs.items.map((org) => orgHasExoM1(client, org.sys.id))
|
|
8245
|
+
);
|
|
8246
|
+
return results.some(Boolean);
|
|
8247
|
+
} catch {
|
|
8248
|
+
return false;
|
|
8249
|
+
}
|
|
8250
|
+
}
|
|
5886
8251
|
export {
|
|
5887
|
-
|
|
8252
|
+
CONVENTIONS_GUIDANCE,
|
|
8253
|
+
CORE_INVARIANTS,
|
|
8254
|
+
ContentfulMcpTools,
|
|
8255
|
+
EXO_DISPOSITION,
|
|
8256
|
+
EXO_M1_FEATURE,
|
|
8257
|
+
SEARCHING_GUIDANCE,
|
|
8258
|
+
hasExoM1Entitlement
|
|
5888
8259
|
};
|