@nextblock-cms/cortex 0.20.3 → 0.21.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/README.md +46 -0
  2. package/client.cjs +1 -0
  3. package/client.es.js +3 -7
  4. package/index.cjs +1 -0
  5. package/index.es.js +24 -277
  6. package/lib/ai-block-generation.cjs +4 -0
  7. package/lib/ai-block-generation.es.js +143 -182
  8. package/lib/ai-client.cjs +1 -0
  9. package/lib/ai-client.d.ts +1 -1
  10. package/lib/ai-client.es.js +101 -135
  11. package/lib/ai-config.cjs +1 -0
  12. package/lib/ai-config.es.js +89 -108
  13. package/lib/ai-cortex-widget-builder.cjs +1 -0
  14. package/lib/ai-cortex-widget-builder.es.js +56 -70
  15. package/lib/ai-global-agent-content-ops-tools.cjs +1 -0
  16. package/lib/ai-global-agent-content-ops-tools.d.ts +1943 -68
  17. package/lib/ai-global-agent-content-ops-tools.es.js +185 -199
  18. package/lib/ai-global-agent-custom-block-tools.cjs +1 -0
  19. package/lib/ai-global-agent-custom-block-tools.d.ts +2160 -95
  20. package/lib/ai-global-agent-custom-block-tools.es.js +226 -223
  21. package/lib/ai-global-agent-db-tools.cjs +1 -0
  22. package/lib/ai-global-agent-db-tools.d.ts +2708 -98
  23. package/lib/ai-global-agent-db-tools.es.js +1013 -986
  24. package/lib/ai-global-agent-ecommerce.cjs +1 -0
  25. package/lib/ai-global-agent-ecommerce.es.js +3 -7
  26. package/lib/ai-global-agent-site-tools.cjs +2 -0
  27. package/lib/ai-global-agent-site-tools.d.ts +10695 -500
  28. package/lib/ai-global-agent-site-tools.es.js +750 -757
  29. package/lib/ai-global-agent-theming-tools.cjs +1 -0
  30. package/lib/ai-global-agent-theming-tools.d.ts +2905 -105
  31. package/lib/ai-global-agent-theming-tools.es.js +326 -396
  32. package/lib/ai-global-agent-tools.cjs +15 -0
  33. package/lib/ai-global-agent-tools.d.ts +4 -2230
  34. package/lib/ai-global-agent-tools.es.js +3899 -4328
  35. package/lib/ai-key-crypto.cjs +1 -0
  36. package/lib/ai-key-crypto.es.js +63 -82
  37. package/lib/ai-key-verification.cjs +1 -0
  38. package/lib/ai-key-verification.es.js +74 -63
  39. package/lib/ai-model-catalog.cjs +1 -0
  40. package/lib/ai-model-catalog.es.js +18 -22
  41. package/lib/ai-model-registry.cjs +2 -0
  42. package/lib/ai-model-registry.es.js +246 -309
  43. package/lib/ai-seo-metadata.cjs +3 -0
  44. package/lib/ai-seo-metadata.es.js +143 -185
  45. package/lib/ai-vision.cjs +3 -0
  46. package/lib/ai-vision.d.ts +6 -6
  47. package/lib/ai-vision.es.js +161 -215
  48. package/lib/block-content-schemas.cjs +1 -0
  49. package/lib/block-content-schemas.es.js +324 -254
  50. package/lib/cortex-widget-registry.cjs +1 -0
  51. package/lib/cortex-widget-registry.es.js +35 -43
  52. package/lib/cortex-widget-schema.cjs +4 -0
  53. package/lib/cortex-widget-schema.es.js +280 -309
  54. package/lib/editor-document-from-html.cjs +1 -0
  55. package/lib/editor-document-from-html.es.js +334 -278
  56. package/lib/fetch-host-guard.cjs +1 -0
  57. package/lib/fetch-host-guard.d.ts +2 -0
  58. package/lib/fetch-host-guard.es.js +30 -0
  59. package/lib/mcp-server.cjs +1 -0
  60. package/lib/mcp-server.es.js +155 -173
  61. package/lib/mcp-tokens.cjs +1 -0
  62. package/lib/mcp-tokens.es.js +95 -107
  63. package/lib/mcp-tool-registry.cjs +5 -0
  64. package/lib/mcp-tool-registry.es.js +533 -411
  65. package/lib/site-brief.cjs +2 -0
  66. package/lib/site-brief.es.js +102 -108
  67. package/lib/vision-image-download.cjs +1 -0
  68. package/lib/vision-image-download.d.ts +43 -0
  69. package/lib/vision-image-download.es.js +120 -0
  70. package/lib/zod-config.cjs +1 -0
  71. package/lib/zod-config.es.js +5 -6
  72. package/package.json +13 -12
  73. package/client.cjs.js +0 -1
  74. package/index.cjs.js +0 -1
  75. package/lib/ai-block-generation.cjs.js +0 -5
  76. package/lib/ai-client.cjs.js +0 -1
  77. package/lib/ai-config.cjs.js +0 -1
  78. package/lib/ai-cortex-widget-builder.cjs.js +0 -1
  79. package/lib/ai-global-agent-content-ops-tools.cjs.js +0 -1
  80. package/lib/ai-global-agent-custom-block-tools.cjs.js +0 -1
  81. package/lib/ai-global-agent-db-tools.cjs.js +0 -1
  82. package/lib/ai-global-agent-ecommerce.cjs.js +0 -1
  83. package/lib/ai-global-agent-site-tools.cjs.js +0 -3
  84. package/lib/ai-global-agent-theming-tools.cjs.js +0 -3
  85. package/lib/ai-global-agent-tools.cjs.js +0 -15
  86. package/lib/ai-key-crypto.cjs.js +0 -1
  87. package/lib/ai-key-verification.cjs.js +0 -1
  88. package/lib/ai-model-catalog.cjs.js +0 -1
  89. package/lib/ai-model-registry.cjs.js +0 -2
  90. package/lib/ai-seo-metadata.cjs.js +0 -4
  91. package/lib/ai-vision.cjs.js +0 -3
  92. package/lib/block-content-schemas.cjs.js +0 -1
  93. package/lib/cortex-widget-registry.cjs.js +0 -1
  94. package/lib/cortex-widget-schema.cjs.js +0 -5
  95. package/lib/editor-document-from-html.cjs.js +0 -1
  96. package/lib/mcp-server.cjs.js +0 -1
  97. package/lib/mcp-tokens.cjs.js +0 -1
  98. package/lib/mcp-tool-registry.cjs.js +0 -6
  99. package/lib/site-brief.cjs.js +0 -2
  100. package/lib/zod-config.cjs.js +0 -1
@@ -1,211 +1,197 @@
1
- import { tool as m } from "ai";
2
- import "./zod-config.es.js";
3
- import { z as r } from "zod";
4
- const $ = "id, file_name, object_key, file_type, width, height, description, folder, created_at";
5
- function f(e) {
6
- if (!e?.supabase)
7
- throw new Error("No database connection is available for this tool.");
8
- return e.supabase;
1
+ import { z as e } from "./zod-config.es.js";
2
+ import { tool as t } from "ai";
3
+ //#region src/lib/ai-global-agent-content-ops-tools.ts
4
+ var n = "id, file_name, object_key, file_type, width, height, description, folder, created_at";
5
+ function r(e) {
6
+ if (!e?.supabase) throw Error("No database connection is available for this tool.");
7
+ return e.supabase;
9
8
  }
10
- function c(e) {
11
- return e ? e instanceof Error ? e.message : typeof e == "object" && "message" in e ? String(e.message) : String(e) : "unknown error";
9
+ function i(e) {
10
+ return e ? e instanceof Error ? e.message : typeof e == "object" && "message" in e ? String(e.message) : String(e) : "unknown error";
12
11
  }
13
- function _(e) {
14
- return e.normalize("NFD").replace(new RegExp("\\p{Diacritic}", "gu"), "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
12
+ function a(e) {
13
+ return e.normalize("NFD").replace(/\p{Diacritic}/gu, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
15
14
  }
16
- const x = r.strictObject({
17
- limit: r.number().int().min(1).max(100).default(30),
18
- query: r.string().trim().max(120).optional().describe('Filter on file name or alt text, e.g. "wormwood" or "laboratory".')
19
- }), E = r.strictObject({
20
- altText: r.string().trim().max(300).optional().describe("Alt text describing the image. Write real alt text — it is what screen readers announce and what search engines index."),
21
- url: r.string().trim().min(1).max(2048).describe("Public https URL of the image to bring into the media library.")
15
+ var o = e.strictObject({
16
+ limit: e.number().int().min(1).max(100).default(30),
17
+ query: e.string().trim().max(120).optional().describe("Filter on file name or alt text, e.g. \"wormwood\" or \"laboratory\".")
18
+ }), s = e.strictObject({
19
+ altText: e.string().trim().max(300).optional().describe("Alt text describing the image. Write real alt text — it is what screen readers announce and what search engines index."),
20
+ url: e.string().trim().min(1).max(2048).describe("Public https URL of the image to bring into the media library.")
22
21
  });
23
- async function v(e, i) {
24
- const t = x.parse(e);
25
- let a = f(i).from("media").select($).order("created_at", { ascending: !1 }).limit(t.limit);
26
- if (t.query) {
27
- const s = `%${t.query}%`;
28
- a = a.or(`file_name.ilike.${s},description.ilike.${s}`);
29
- }
30
- const { data: u, error: l } = await a;
31
- if (l)
32
- throw new Error(`Could not read the media library: ${c(l)}`);
33
- return { count: (u ?? []).length, media: u ?? [], success: !0 };
22
+ async function c(e, t) {
23
+ let a = o.parse(e), s = r(t).from("media").select(n).order("created_at", { ascending: !1 }).limit(a.limit);
24
+ if (a.query) {
25
+ let e = `%${a.query}%`;
26
+ s = s.or(`file_name.ilike.${e},description.ilike.${e}`);
27
+ }
28
+ let { data: c, error: l } = await s;
29
+ if (l) throw Error(`Could not read the media library: ${i(l)}`);
30
+ return {
31
+ count: (c ?? []).length,
32
+ media: c ?? [],
33
+ success: !0
34
+ };
34
35
  }
35
- async function I(e, i) {
36
- const t = E.parse(e), o = i?.importExternalImage;
37
- if (!o)
38
- throw new Error("Media import is not available on this connection.");
39
- const a = await o({
40
- ...t.altText ? { altText: t.altText } : {},
41
- url: t.url
42
- });
43
- if ("error" in a)
44
- throw new Error(`Could not import that image: ${a.error}`);
45
- return { mediaId: a.id, mutationExecuted: !0, success: !0 };
36
+ async function l(e, t) {
37
+ let n = s.parse(e), r = t?.importExternalImage;
38
+ if (!r) throw Error("Media import is not available on this connection.");
39
+ let i = await r({
40
+ ...n.altText ? { altText: n.altText } : {},
41
+ url: n.url
42
+ });
43
+ if ("error" in i) throw Error(`Could not import that image: ${i.error}`);
44
+ return {
45
+ mediaId: i.id,
46
+ mutationExecuted: !0,
47
+ success: !0
48
+ };
46
49
  }
47
- const C = r.strictObject({
48
- code: r.string().trim().min(2).max(10).describe('Locale code, e.g. "fr", "es", "de". Re-using an existing code updates that language.'),
49
- is_active: r.boolean().default(!0).describe("Inactive languages are hidden from the public switcher."),
50
- is_default: r.boolean().default(!1).describe("Make this the site default. Only one language can be default; setting it clears the others."),
51
- name: r.string().trim().min(1).max(80).describe('Display name, e.g. "Français".')
50
+ var u = e.strictObject({
51
+ code: e.string().trim().min(2).max(10).describe("Locale code, e.g. \"fr\", \"es\", \"de\". Re-using an existing code updates that language."),
52
+ is_active: e.boolean().default(!0).describe("Inactive languages are hidden from the public switcher."),
53
+ is_default: e.boolean().default(!1).describe("Make this the site default. Only one language can be default; setting it clears the others."),
54
+ name: e.string().trim().min(1).max(80).describe("Display name, e.g. \"Français\".")
52
55
  });
53
- async function L(e, i) {
54
- const t = C.parse(e), o = f(i), a = t.code.toLowerCase(), { data: u } = await o.from("languages").select("id, code").eq("code", a).maybeSingle(), l = {
55
- code: a,
56
- is_active: t.is_active,
57
- name: t.name
58
- };
59
- let s = u?.id;
60
- if (s) {
61
- const { error: d } = await o.from("languages").update(l).eq("id", s);
62
- if (d)
63
- throw new Error(`Could not update the "${a}" language: ${c(d)}`);
64
- } else {
65
- const { data: d, error: n } = await o.from("languages").insert(l).select("id").single();
66
- if (n || !d?.id)
67
- throw new Error(`Could not create the "${a}" language: ${c(n)}`);
68
- s = d.id;
69
- }
70
- if (t.is_default) {
71
- const { error: d } = await o.from("languages").update({ is_default: !1 }).neq("id", s);
72
- if (d)
73
- throw new Error(`Could not clear the previous default language: ${c(d)}`);
74
- const { error: n } = await o.from("languages").update({ is_default: !0 }).eq("id", s);
75
- if (n)
76
- throw new Error(`Could not set the default language: ${c(n)}`);
77
- }
78
- try {
79
- i?.revalidatePath?.("/", "layout");
80
- } catch {
81
- }
82
- return {
83
- code: a,
84
- created: !u,
85
- languageId: s,
86
- mutationExecuted: !0,
87
- success: !0
88
- };
56
+ async function d(e, t) {
57
+ let n = u.parse(e), a = r(t), o = n.code.toLowerCase(), { data: s } = await a.from("languages").select("id, code").eq("code", o).maybeSingle(), c = {
58
+ code: o,
59
+ is_active: n.is_active,
60
+ name: n.name
61
+ }, l = s?.id;
62
+ if (l) {
63
+ let { error: e } = await a.from("languages").update(c).eq("id", l);
64
+ if (e) throw Error(`Could not update the "${o}" language: ${i(e)}`);
65
+ } else {
66
+ let { data: e, error: t } = await a.from("languages").insert(c).select("id").single();
67
+ if (t || !e?.id) throw Error(`Could not create the "${o}" language: ${i(t)}`);
68
+ l = e.id;
69
+ }
70
+ if (n.is_default) {
71
+ let { error: e } = await a.from("languages").update({ is_default: !1 }).neq("id", l);
72
+ if (e) throw Error(`Could not clear the previous default language: ${i(e)}`);
73
+ let { error: t } = await a.from("languages").update({ is_default: !0 }).eq("id", l);
74
+ if (t) throw Error(`Could not set the default language: ${i(t)}`);
75
+ }
76
+ try {
77
+ t?.revalidatePath?.("/", "layout");
78
+ } catch {}
79
+ return {
80
+ code: o,
81
+ created: !s,
82
+ languageId: l,
83
+ mutationExecuted: !0,
84
+ success: !0
85
+ };
89
86
  }
90
- const S = r.strictObject({
91
- action: r.enum(["upsert", "delete"]).default("upsert"),
92
- description: r.string().max(1e3).nullable().optional(),
93
- name: r.string().trim().min(1).max(120).describe('Category name, e.g. "Digestive Health".'),
94
- name_translations: r.record(r.string(), r.string()).optional().describe('Translated names keyed by locale code, e.g. { "fr": "Santé digestive" }.'),
95
- productSlugs: r.array(r.string().trim().min(1).max(300)).max(100).optional().describe("Product slugs to place in this category. Replaces the category's current membership."),
96
- slug: r.string().trim().min(1).max(120).optional().describe("URL slug. Derived from the name when omitted. Re-using a slug updates that category.")
87
+ var f = e.strictObject({
88
+ action: e.enum(["upsert", "delete"]).default("upsert"),
89
+ description: e.string().max(1e3).nullable().optional(),
90
+ name: e.string().trim().min(1).max(120).describe("Category name, e.g. \"Digestive Health\"."),
91
+ name_translations: e.record(e.string(), e.string()).optional().describe("Translated names keyed by locale code, e.g. { \"fr\": \"Santé digestive\" }."),
92
+ productSlugs: e.array(e.string().trim().min(1).max(300)).max(100).optional().describe("Product slugs to place in this category. Replaces the category's current membership."),
93
+ slug: e.string().trim().min(1).max(120).optional().describe("URL slug. Derived from the name when omitted. Re-using a slug updates that category.")
97
94
  });
98
- async function k(e, i) {
99
- const t = S.parse(e), o = f(i), a = t.slug ? _(t.slug) : _(t.name), { data: u } = await o.from("categories").select("id, name, slug").eq("slug", a).maybeSingle();
100
- if (t.action === "delete") {
101
- if (!u?.id)
102
- return {
103
- message: `No category with slug "${a}".`,
104
- mutationExecuted: !1,
105
- success: !1
106
- };
107
- const { error: n } = await o.from("categories").delete().eq("id", u.id);
108
- if (n)
109
- throw new Error(`Could not delete the category: ${c(n)}`);
110
- return { action: "delete", mutationExecuted: !0, slug: a, success: !0 };
111
- }
112
- const l = {
113
- name: t.name,
114
- slug: a,
115
- ...t.description !== void 0 ? { description: t.description } : {},
116
- ...t.name_translations ? { name_translations: t.name_translations } : {}
117
- };
118
- let s = u?.id;
119
- if (s) {
120
- const { error: n } = await o.from("categories").update(l).eq("id", s);
121
- if (n)
122
- throw new Error(`Could not update the category: ${c(n)}`);
123
- } else {
124
- const { data: n, error: g } = await o.from("categories").insert(l).select("id").single();
125
- if (g || !n?.id)
126
- throw new Error(`Could not create the category: ${c(g)}`);
127
- s = n.id;
128
- }
129
- let d = 0;
130
- if (t.productSlugs) {
131
- const { data: n, error: g } = await o.from("products").select("id, slug").in("slug", t.productSlugs);
132
- if (g)
133
- throw new Error(`Could not resolve those products: ${c(g)}`);
134
- const p = n ?? [], y = t.productSlugs.filter(
135
- (h) => !p.some((w) => w.slug === h)
136
- );
137
- if (y.length > 0)
138
- throw new Error(`No product found for slug(s): ${y.join(", ")}.`);
139
- const { error: b } = await o.from("product_categories").delete().eq("category_id", s);
140
- if (b)
141
- throw new Error(`Could not clear the category's products: ${c(b)}`);
142
- if (p.length > 0) {
143
- const { error: h } = await o.from("product_categories").insert(p.map((w) => ({ category_id: s, product_id: w.id })));
144
- if (h)
145
- throw new Error(`Could not add products to the category: ${c(h)}`);
146
- d = p.length;
147
- }
148
- }
149
- return {
150
- categoryId: s,
151
- created: !u,
152
- linkedProducts: d,
153
- mutationExecuted: !0,
154
- slug: a,
155
- success: !0
156
- };
95
+ async function p(e, t) {
96
+ let n = f.parse(e), o = r(t), s = n.slug ? a(n.slug) : a(n.name), { data: c } = await o.from("categories").select("id, name, slug").eq("slug", s).maybeSingle();
97
+ if (n.action === "delete") {
98
+ if (!c?.id) return {
99
+ message: `No category with slug "${s}".`,
100
+ mutationExecuted: !1,
101
+ success: !1
102
+ };
103
+ let { error: e } = await o.from("categories").delete().eq("id", c.id);
104
+ if (e) throw Error(`Could not delete the category: ${i(e)}`);
105
+ return {
106
+ action: "delete",
107
+ mutationExecuted: !0,
108
+ slug: s,
109
+ success: !0
110
+ };
111
+ }
112
+ let l = {
113
+ name: n.name,
114
+ slug: s,
115
+ ...n.description === void 0 ? {} : { description: n.description },
116
+ ...n.name_translations ? { name_translations: n.name_translations } : {}
117
+ }, u = c?.id;
118
+ if (u) {
119
+ let { error: e } = await o.from("categories").update(l).eq("id", u);
120
+ if (e) throw Error(`Could not update the category: ${i(e)}`);
121
+ } else {
122
+ let { data: e, error: t } = await o.from("categories").insert(l).select("id").single();
123
+ if (t || !e?.id) throw Error(`Could not create the category: ${i(t)}`);
124
+ u = e.id;
125
+ }
126
+ let d = 0;
127
+ if (n.productSlugs) {
128
+ let { data: e, error: t } = await o.from("products").select("id, slug").in("slug", n.productSlugs);
129
+ if (t) throw Error(`Could not resolve those products: ${i(t)}`);
130
+ let r = e ?? [], a = n.productSlugs.filter((e) => !r.some((t) => t.slug === e));
131
+ if (a.length > 0) throw Error(`No product found for slug(s): ${a.join(", ")}.`);
132
+ let { error: s } = await o.from("product_categories").delete().eq("category_id", u);
133
+ if (s) throw Error(`Could not clear the category's products: ${i(s)}`);
134
+ if (r.length > 0) {
135
+ let { error: e } = await o.from("product_categories").insert(r.map((e) => ({
136
+ category_id: u,
137
+ product_id: e.id
138
+ })));
139
+ if (e) throw Error(`Could not add products to the category: ${i(e)}`);
140
+ d = r.length;
141
+ }
142
+ }
143
+ return {
144
+ categoryId: u,
145
+ created: !c,
146
+ linkedProducts: d,
147
+ mutationExecuted: !0,
148
+ slug: s,
149
+ success: !0
150
+ };
157
151
  }
158
- const q = r.strictObject({});
159
- async function R(e, i) {
160
- const t = f(i), { data: o, error: a } = await t.from("categories").select("id, name, slug, description, name_translations").order("name");
161
- if (a)
162
- throw new Error(`Could not read the categories: ${c(a)}`);
163
- return { categories: o ?? [], count: (o ?? []).length, success: !0 };
152
+ var m = e.strictObject({});
153
+ async function h(e, t) {
154
+ let { data: n, error: a } = await r(t).from("categories").select("id, name, slug, description, name_translations").order("name");
155
+ if (a) throw Error(`Could not read the categories: ${i(a)}`);
156
+ return {
157
+ categories: n ?? [],
158
+ count: (n ?? []).length,
159
+ success: !0
160
+ };
164
161
  }
165
- function O(e) {
166
- return {
167
- list_media: m({
168
- description: "Browse the media library: file names, alt text, dimensions, and media ids. Read-only. Call this BEFORE importing an image so you reuse what is already stored instead of creating a duplicate — the returned `id` can be passed anywhere a media id or image reference is accepted (feature_image_id, product images, an image block).",
169
- execute: (i) => v(i, e),
170
- inputSchema: x,
171
- strict: !0
172
- }),
173
- list_product_categories: m({
174
- description: "List the product categories, with their slugs and translated names. Read-only. Use before creating one so an existing category is reused, and to get ids for a product_grid block filtered by category.",
175
- execute: (i) => R(i, e),
176
- inputSchema: q,
177
- strict: !0
178
- }),
179
- manage_language: m({
180
- description: "Add or update a site language, so the CMS can hold content in that locale. Creating the language is the FIRST step of making a site multilingual — translate_page cannot target a locale that does not exist yet. Re-using a code updates that language; set is_default to change the site default.",
181
- execute: (i) => L(i, e),
182
- inputSchema: C,
183
- strict: !0
184
- }),
185
- manage_product_category: m({
186
- description: "Create, update, or delete a product category, and optionally set exactly which products belong to it by slug. Categories are what a product_grid block filters on, so create these before building a shop page that shows one section of the catalogue. Passing productSlugs REPLACES the category's membership.",
187
- execute: (i) => k(i, e),
188
- inputSchema: S,
189
- strict: !0
190
- }),
191
- upload_media: m({
192
- description: "Import an image from a public https URL into the media library and return its media id, without attaching it to anything. Useful when you want one asset reused across several places — otherwise passing the URL straight to create_cms_product `images` or a page/post `feature_image_id` imports it in the same call. Check list_media first to avoid duplicates.",
193
- execute: (i) => I(i, e),
194
- inputSchema: E,
195
- strict: !0
196
- })
197
- };
162
+ function g(e) {
163
+ return {
164
+ list_media: t({
165
+ description: "Browse the media library: file names, alt text, dimensions, and media ids. Read-only. Call this BEFORE importing an image so you reuse what is already stored instead of creating a duplicate — the returned `id` can be passed anywhere a media id or image reference is accepted (feature_image_id, product images, an image block).",
166
+ execute: (t) => c(t, e),
167
+ inputSchema: o,
168
+ strict: !0
169
+ }),
170
+ list_product_categories: t({
171
+ description: "List the product categories, with their slugs and translated names. Read-only. Use before creating one so an existing category is reused, and to get ids for a product_grid block filtered by category.",
172
+ execute: (t) => h(t, e),
173
+ inputSchema: m,
174
+ strict: !0
175
+ }),
176
+ manage_language: t({
177
+ description: "Add or update a site language, so the CMS can hold content in that locale. Creating the language is the FIRST step of making a site multilingual — translate_page cannot target a locale that does not exist yet. Re-using a code updates that language; set is_default to change the site default.",
178
+ execute: (t) => d(t, e),
179
+ inputSchema: u,
180
+ strict: !0
181
+ }),
182
+ manage_product_category: t({
183
+ description: "Create, update, or delete a product category, and optionally set exactly which products belong to it by slug. Categories are what a product_grid block filters on, so create these before building a shop page that shows one section of the catalogue. Passing productSlugs REPLACES the category's membership.",
184
+ execute: (t) => p(t, e),
185
+ inputSchema: f,
186
+ strict: !0
187
+ }),
188
+ upload_media: t({
189
+ description: "Import an image from a public https URL into the media library and return its media id, without attaching it to anything. Useful when you want one asset reused across several places — otherwise passing the URL straight to create_cms_product `images` or a page/post `feature_image_id` imports it in the same call. Check list_media first to avoid duplicates.",
190
+ execute: (t) => l(t, e),
191
+ inputSchema: s,
192
+ strict: !0
193
+ })
194
+ };
198
195
  }
199
- export {
200
- O as createCortexContentOpsTools,
201
- v as executeListMedia,
202
- R as executeListProductCategories,
203
- L as executeManageLanguage,
204
- k as executeManageProductCategory,
205
- I as executeUploadMedia,
206
- x as listMediaInputSchema,
207
- q as listProductCategoriesInputSchema,
208
- C as manageLanguageInputSchema,
209
- S as manageProductCategoryInputSchema,
210
- E as uploadMediaInputSchema
211
- };
196
+ //#endregion
197
+ export { g as createCortexContentOpsTools, c as executeListMedia, h as executeListProductCategories, d as executeManageLanguage, p as executeManageProductCategory, l as executeUploadMedia, o as listMediaInputSchema, m as listProductCategoriesInputSchema, u as manageLanguageInputSchema, f as manageProductCategoryInputSchema, s as uploadMediaInputSchema };
@@ -0,0 +1 @@
1
+ require("./zod-config.cjs");let e=require("ai"),t=require("next/cache"),n=require("zod");var r=`id, slug, name, description, fields, layout_schema, is_original`,i=n.z.strictObject({context:n.z.string().trim().max(3e3).optional().describe(`Optional extra constraints or brand/style guidance for the generated block.`),prompt:n.z.string().trim().min(3).max(4e3).describe(`Natural-language description of the custom block, including the fields it needs and the visual style. Example: "A product card with a title, image, price, and a button that links to the product page."`)}),a=n.z.strictObject({prompt:n.z.string().trim().min(3).max(4e3).describe(`Description of the changes to apply. The block is regenerated using its existing definition as context.`),slug:n.z.string().trim().min(1).max(120).describe(`Slug of the existing custom block to edit.`)}),o=n.z.strictObject({slug:n.z.string().trim().min(1).max(120).describe(`Slug of the custom block definition to delete.`)}),s=n.z.strictObject({query:n.z.string().trim().max(120).optional().describe(`Optional text filter on name or slug.`)});function c(e){if(!e?.supabase)throw Error(`A Supabase service client is required to manage custom block definitions.`);return e.supabase}function l(e){if(!e?.actorUserId)throw Error(`Managing custom block definitions requires an authenticated admin actor.`);return e.actorUserId}function u(e){return JSON.parse(JSON.stringify(e))}function d(e){let t=Array.isArray(e?.fields)?e.fields:[];return{fieldCount:t.length,fields:t.map(e=>({key:e?.key,label:e?.label,type:e?.type})),id:e?.id,name:e?.name,slug:e?.slug}}var f=24e3;function p(e){let t=`You are editing an existing custom block named "${e.name??`Untitled`}". Keep its overall purpose and only apply the requested changes.`,n=`${t} Existing definition: ${JSON.stringify({fields:e.fields,layout_schema:e.layout_schema,name:e.name})}`;return n.length<=f?n:`${t} Existing fields: ${JSON.stringify({fields:e.fields,name:e.name})} (The existing layout was too large to include — rebuild a layout that renders these fields.)`.slice(0,f)}function m(e,t){let n=t?.cortexAiApiKey||void 0;return{apiKey:n,context:e.context,modelSelection:n&&t?.cortexAiModelSelection?t.cortexAiModelSelection:void 0,prompt:e.prompt}}function h(e){try{let n=t.revalidatePath,r=t.revalidateTag;r(`custom-block-definitions`,`max`),e?.id&&r(`custom-block-definitions:${e.id}`,`max`),e?.slug&&r(`custom-block-definitions:${e.slug}`,`max`),r(`dynamic-layout-engine`,`max`),n(`/cms/custom-blocks`),n(`/cms/blocks`)}catch{}}function g(e){return(e||``).replace(/\s+/g,` `).trim().toUpperCase()}function _(e){return`CONFIRM DELETE CUSTOM BLOCK ${e.toUpperCase()}`}function v(e,t){return e?.skipConfirmation?!0:g(e?.latestUserMessage).includes(g(t))}function y(e){if(e&&typeof e==`object`){let t=e;if(t.code===`23505`)return`A custom block with that slug already exists. Choose a different name or edit the existing one.`;if(typeof t.message==`string`&&t.message)return t.message}return e instanceof Error?e.message:`Unknown error.`}async function b(e,t){try{let n=c(t);l(t);let[{generateCortexWidgetDefinition:r},{insertCortexWidgetDefinition:i}]=await Promise.all([Promise.resolve().then(()=>require("./ai-cortex-widget-builder.cjs")),Promise.resolve().then(()=>require("./cortex-widget-registry.cjs"))]),a=await i(n,(await r(m(e,t))).definition);return h(a),{definition:d(a),editUrl:`/cms/custom-blocks/${a.id}/edit`,mutationExecuted:!0,success:!0}}catch(e){return{mutationExecuted:!1,message:y(e),success:!1}}}async function x(e,t){try{let n=c(t);l(t);let{data:i}=await n.from(`custom_block_definitions`).select(r).eq(`slug`,e.slug).maybeSingle();if(!i)return{mutationExecuted:!1,message:`No custom block found with slug "${e.slug}".`,success:!1};let[{generateCortexWidgetDefinition:a},{customBlockDefinitionCreateSchema:o}]=await Promise.all([Promise.resolve().then(()=>require("./ai-cortex-widget-builder.cjs")),import(`@nextblock-cms/utils/custom-blocks`)]),s=await a(m({context:p(i),prompt:e.prompt},t)),f=o.parse({...s.definition,is_original:i.is_original,slug:i.slug}),{data:g,error:_}=await n.from(`custom_block_definitions`).update({description:f.description,fields:u(f.fields),layout_schema:u(f.layout_schema),name:f.name}).eq(`id`,i.id).select(r).single();return _||!g?{mutationExecuted:!1,message:_?.message??`Failed to update custom block.`,success:!1}:(h(g),{definition:d(g),editUrl:`/cms/custom-blocks/${i.id}/edit`,mutationExecuted:!0,success:!0})}catch(e){return{mutationExecuted:!1,message:y(e),success:!1}}}async function S(e,t){try{let n=c(t);l(t);let{data:r}=await n.from(`custom_block_definitions`).select(`id, slug, name`).eq(`slug`,e.slug).maybeSingle();if(!r)return{mutationExecuted:!1,message:`No custom block found with slug "${e.slug}".`,success:!1};let i=_(r.slug);if(!v(t,i))return{confirmationPhrase:i,mutationExecuted:!1,preview:{summary:`Delete the custom block "${r.name}" (${r.slug}). Pages still using it will stop rendering it until replaced. This cannot be undone.`},requiresConfirmation:!0,success:!0};let{error:a}=await n.from(`custom_block_definitions`).delete().eq(`id`,r.id);return a?{mutationExecuted:!1,message:`Failed to delete custom block: ${a.message}`,success:!1}:(h(r),{deleted:{name:r.name,slug:r.slug},mutationExecuted:!0,success:!0})}catch(e){return{mutationExecuted:!1,message:y(e),success:!1}}}async function C(e,t){try{let{data:n,error:r}=await c(t).from(`custom_block_definitions`).select(`id, slug, name, description, fields, is_original`).order(`name`,{ascending:!0});if(r)return{message:r.message,success:!1};let i=Array.isArray(n)?n:[];if(e.query){let t=e.query.toLowerCase();i=i.filter(e=>String(e.name||``).toLowerCase().includes(t)||String(e.slug||``).toLowerCase().includes(t))}return{blocks:i.map(e=>d(e)),count:i.length,success:!0}}catch(e){return{message:y(e),success:!1}}}function w(t){return{create_custom_block:(0,e.tool)({description:`Create a brand-new reusable custom block definition from a natural-language description (for example "a product card with title, image, price, and a button linking to the product page"). This is a GLOBAL block-library builder and does NOT require an open page, post, or product. It generates the field schema and Tailwind layout and saves it so the block can be added to any page afterward. Additive and reversible; executes immediately without a confirmation phrase.`,execute:e=>b(e,t),inputSchema:i,strict:!0}),delete_custom_block:(0,e.tool)({description:`Delete a custom block definition by slug. Mutating: first returns a confirmation phrase; only executes after the user replies with the exact phrase. Use list_custom_blocks first if you are unsure of the slug.`,execute:e=>S(e,t),inputSchema:o,strict:!0}),list_custom_blocks:(0,e.tool)({description:`List the existing custom block definitions (slug, name, and fields). Read-only and does not require page context. Use it to find the slug of a block to edit or delete.`,execute:e=>C(e,t),inputSchema:s,strict:!0}),update_custom_block:(0,e.tool)({description:`Edit an existing custom block definition (identified by slug) from a new natural-language description. The block is regenerated with its current definition as context and keeps its slug so existing placements keep working. Executes immediately.`,execute:e=>x(e,t),inputSchema:a,strict:!0})}}exports.createCortexCustomBlockTools=w,exports.createCustomBlockInputSchema=i,exports.deleteCustomBlockInputSchema=o,exports.executeCreateCustomBlock=b,exports.executeDeleteCustomBlock=S,exports.executeListCustomBlocks=C,exports.executeUpdateCustomBlock=x,exports.listCustomBlocksInputSchema=s,exports.updateCustomBlockInputSchema=a;