@nextblock-cms/cortex 0.18.1 → 0.18.3

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.
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require("./zod-config.cjs.js");const e=require("zod"),c="cortex_ai_site_brief",m="cortex_ai_build_session",l=e.z.string().trim().min(2).max(10),p=e.z.strictObject({purpose:e.z.string().trim().max(600).optional().describe("What this page is for and what a visitor should do there."),sections:e.z.array(e.z.string().trim().min(1).max(200)).max(20).optional().describe('Planned sections, top to bottom, e.g. ["hero", "services", "testimonials", "contact form"].'),slug:e.z.string().trim().min(1).max(120).describe('URL slug in the primary language, e.g. "home", "services", "contact".'),title:e.z.string().trim().min(1).max(200)}),u=e.z.strictObject({accent_color:e.z.string().trim().max(40).optional(),color_scheme:e.z.enum(["light","dark"]).optional().describe("Overall look the client prefers."),font_style:e.z.string().trim().max(120).optional().describe('e.g. "clean sans-serif", "elegant serif".'),logo_notes:e.z.string().trim().max(600).optional().describe("Whether they have a logo, where it is, or what to do meanwhile."),primary_color:e.z.string().trim().max(40).optional().describe('Hex or plain colour name, e.g. "#1e6f5c" or "forest green".'),secondary_color:e.z.string().trim().max(40).optional(),style_keywords:e.z.array(e.z.string().trim().min(1).max(60)).max(12).optional().describe('e.g. ["minimal", "warm", "premium"].'),tone:e.z.string().trim().max(200).optional().describe('Voice for the copy, e.g. "friendly and plain-spoken".')}).partial(),d=e.z.strictObject({address:e.z.string().trim().max(400).optional(),email:e.z.string().trim().max(200).optional(),hours:e.z.string().trim().max(400).optional(),phone:e.z.string().trim().max(60).optional(),social:e.z.array(e.z.strictObject({platform:e.z.string().trim().min(1).max(60),url:e.z.string().trim().min(1).max(2048)})).max(12).optional()}).partial(),r=e.z.strictObject({audience:e.z.string().trim().max(1e3).optional().describe("Who the site is for."),brand:u.optional(),business_name:e.z.string().trim().min(1).max(160),contact:d.optional(),description:e.z.string().trim().max(3e3).optional().describe("What the business does, in the client's own words where possible."),ecommerce:e.z.strictObject({enabled:e.z.boolean().default(!1),products_summary:e.z.string().trim().max(1e3).optional()}).optional(),goals:e.z.array(e.z.string().trim().min(1).max(300)).max(10).optional().describe('What the site must achieve, e.g. ["get quote requests", "show the menu"].'),keep_existing_content:e.z.boolean().default(!1).describe("true when the client wants existing pages/posts kept rather than replaced."),languages:e.z.array(l).min(1).max(10).default(["en"]).describe("Locale codes the public site must offer, primary first."),notes:e.z.string().trim().max(4e3).optional().describe("Anything else the client said that matters."),pages:e.z.array(p).max(30).default([]).describe('The pages to build. A one-page landing site is a single "home" entry.'),primary_language:l.default("en"),site_type:e.z.enum(["landing-page","multi-page","blog","store","portfolio","other"]).default("multi-page"),status:e.z.enum(["draft","confirmed","built"]).default("draft").describe("draft while interviewing, confirmed once the client approved the plan, built when the build finished."),tagline:e.z.string().trim().max(200).optional(),updated_at:e.z.string().max(80).optional()}),g=r.partial(),h=e.z.strictObject({actorUserId:e.z.string().min(1),createdAt:e.z.string().min(1),expiresAt:e.z.string().min(1),id:e.z.string().min(1),summary:e.z.string().max(4e3)});function _(t){const o=r.safeParse(t);return o.success?o.data:null}function x(t,o){if(!t||!o.actorUserId||t.actorUserId!==o.actorUserId)return!1;const i=Date.parse(t.expiresAt),s=(o.now??new Date).getTime();return Number.isFinite(i)&&i>s}function f(t){const o=[`Business: ${t.business_name}${t.tagline?` — ${t.tagline}`:""}`];t.description&&o.push(`What they do: ${t.description}`),t.audience&&o.push(`Audience: ${t.audience}`),t.goals?.length&&o.push(`Goals: ${t.goals.join("; ")}`),o.push(`Site type: ${t.site_type}. Languages: ${t.languages.join(", ")} (primary ${t.primary_language}).`),t.pages.length>0&&o.push(`Pages: ${t.pages.map(n=>`${n.title} (/${n.slug})${n.purpose?` — ${n.purpose}`:""}`).join("; ")}`);const i=t.brand;if(i&&Object.keys(i).length>0){const n=[i.primary_color?`primary ${i.primary_color}`:null,i.secondary_color?`secondary ${i.secondary_color}`:null,i.accent_color?`accent ${i.accent_color}`:null,i.color_scheme?`${i.color_scheme} scheme`:null,i.font_style?`fonts: ${i.font_style}`:null,i.tone?`tone: ${i.tone}`:null,i.style_keywords?.length?`style: ${i.style_keywords.join(", ")}`:null,i.logo_notes?`logo: ${i.logo_notes}`:null].filter(Boolean);n.length>0&&o.push(`Brand: ${n.join("; ")}`)}const s=t.contact;if(s&&Object.keys(s).length>0){const n=[s.email?`email ${s.email}`:null,s.phone?`phone ${s.phone}`:null,s.address?`address ${s.address}`:null,s.hours?`hours ${s.hours}`:null,s.social?.length?`social: ${s.social.map(a=>`${a.platform} ${a.url}`).join(", ")}`:null].filter(Boolean);n.length>0&&o.push(`Contact: ${n.join("; ")}`)}return t.ecommerce?.enabled&&o.push(`Ecommerce: yes${t.ecommerce.products_summary?` — ${t.ecommerce.products_summary}`:""}`),t.keep_existing_content&&o.push("Keep existing content: yes (do not wipe pages or posts)."),t.notes&&o.push(`Notes: ${t.notes}`),o.push(`Brief status: ${t.status}.`),o.join(`
2
- `)}exports.CORTEX_AI_BUILD_SESSION_SETTING_KEY=m;exports.CORTEX_AI_SITE_BRIEF_SETTING_KEY=c;exports.cortexBuildSessionSchema=h;exports.cortexSiteBriefInputSchema=g;exports.cortexSiteBriefSchema=r;exports.formatCortexSiteBriefForPrompt=f;exports.isCortexBuildSessionUsable=x;exports.safeParseCortexSiteBrief=_;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require("./zod-config.cjs.js");const e=require("zod"),c="cortex_ai_site_brief",m="cortex_ai_build_session",l=e.z.string().trim().min(2).max(10),p=e.z.strictObject({purpose:e.z.string().trim().max(600).optional().describe("What this page is for and what a visitor should do there."),sections:e.z.array(e.z.string().trim().min(1).max(200)).max(20).optional().describe('Planned sections, top to bottom, e.g. ["hero", "services", "testimonials", "contact form"].'),slug:e.z.string().trim().min(1).max(120).describe('URL slug in the primary language, e.g. "home", "services", "contact".'),title:e.z.string().trim().min(1).max(200)}),u=e.z.strictObject({accent_color:e.z.string().trim().max(40).optional(),color_scheme:e.z.enum(["light","dark"]).optional().describe("Overall look the client prefers."),font_style:e.z.string().trim().max(120).optional().describe('e.g. "clean sans-serif", "elegant serif".'),logo_notes:e.z.string().trim().max(600).optional().describe("Whether they have a logo, where it is, or what to do meanwhile."),primary_color:e.z.string().trim().max(40).optional().describe('Hex or plain colour name, e.g. "#1e6f5c" or "forest green".'),secondary_color:e.z.string().trim().max(40).optional(),style_keywords:e.z.array(e.z.string().trim().min(1).max(60)).max(12).optional().describe('e.g. ["minimal", "warm", "premium"].'),tone:e.z.string().trim().max(200).optional().describe('Voice for the copy, e.g. "friendly and plain-spoken".')}).partial(),d=e.z.strictObject({address:e.z.string().trim().max(400).optional(),email:e.z.string().trim().max(200).optional(),hours:e.z.string().trim().max(400).optional(),phone:e.z.string().trim().max(60).optional(),social:e.z.array(e.z.strictObject({platform:e.z.string().trim().min(1).max(60),url:e.z.string().trim().min(1).max(2048)})).max(12).optional()}).partial(),r=e.z.strictObject({audience:e.z.string().trim().max(1e3).optional().describe("Who the site is for."),brand:u.optional(),business_name:e.z.string().trim().min(1).max(160),contact:d.optional(),description:e.z.string().trim().max(3e3).optional().describe("What the business does, in the client's own words where possible."),ecommerce:e.z.strictObject({enabled:e.z.boolean().default(!1),products_summary:e.z.string().trim().max(1e3).optional()}).optional(),goals:e.z.array(e.z.string().trim().min(1).max(300)).max(10).optional().describe('What the site must achieve, e.g. ["get quote requests", "show the menu"].'),keep_existing_content:e.z.boolean().default(!1).describe("true when the client wants existing pages/posts kept rather than replaced."),languages:e.z.array(l).min(1).max(10).default(["en"]).describe("Locale codes the public site must offer, primary first."),notes:e.z.string().trim().max(4e3).optional().describe("Anything else the client said that matters."),pages:e.z.array(p).max(30).default([]).describe('The pages to build. A one-page landing site is a single "home" entry.'),primary_language:l.default("en"),site_type:e.z.enum(["landing-page","multi-page","blog","store","portfolio","other"]).default("multi-page"),status:e.z.enum(["draft","confirmed","built"]).default("draft").describe("draft while interviewing, confirmed once the client approved the plan, built when the build finished."),tagline:e.z.string().trim().max(200).optional(),updated_at:e.z.string().max(80).optional()}),g=r.partial(),h=e.z.strictObject({actorUserId:e.z.string().min(1),createdAt:e.z.string().min(1),expiresAt:e.z.string().min(1),id:e.z.string().min(1),summary:e.z.string().max(4e3)});function _(t){const o=r.safeParse(t);return o.success?o.data:null}function x(t){return!!(t&&t.business_name.trim()&&t.description?.trim())}function f(t,o){if(!t||!o.actorUserId||t.actorUserId!==o.actorUserId)return!1;const i=Date.parse(t.expiresAt),s=(o.now??new Date).getTime();return Number.isFinite(i)&&i>s}function z(t){const o=[`Business: ${t.business_name}${t.tagline?` — ${t.tagline}`:""}`];t.description&&o.push(`What they do: ${t.description}`),t.audience&&o.push(`Audience: ${t.audience}`),t.goals?.length&&o.push(`Goals: ${t.goals.join("; ")}`),o.push(`Site type: ${t.site_type}. Languages: ${t.languages.join(", ")} (primary ${t.primary_language}).`),t.pages.length>0&&o.push(`Pages: ${t.pages.map(n=>`${n.title} (/${n.slug})${n.purpose?` — ${n.purpose}`:""}`).join("; ")}`);const i=t.brand;if(i&&Object.keys(i).length>0){const n=[i.primary_color?`primary ${i.primary_color}`:null,i.secondary_color?`secondary ${i.secondary_color}`:null,i.accent_color?`accent ${i.accent_color}`:null,i.color_scheme?`${i.color_scheme} scheme`:null,i.font_style?`fonts: ${i.font_style}`:null,i.tone?`tone: ${i.tone}`:null,i.style_keywords?.length?`style: ${i.style_keywords.join(", ")}`:null,i.logo_notes?`logo: ${i.logo_notes}`:null].filter(Boolean);n.length>0&&o.push(`Brand: ${n.join("; ")}`)}const s=t.contact;if(s&&Object.keys(s).length>0){const n=[s.email?`email ${s.email}`:null,s.phone?`phone ${s.phone}`:null,s.address?`address ${s.address}`:null,s.hours?`hours ${s.hours}`:null,s.social?.length?`social: ${s.social.map(a=>`${a.platform} ${a.url}`).join(", ")}`:null].filter(Boolean);n.length>0&&o.push(`Contact: ${n.join("; ")}`)}return t.ecommerce?.enabled&&o.push(`Ecommerce: yes${t.ecommerce.products_summary?` — ${t.ecommerce.products_summary}`:""}`),t.keep_existing_content&&o.push("Keep existing content: yes (do not wipe pages or posts)."),t.notes&&o.push(`Notes: ${t.notes}`),o.push(`Brief status: ${t.status}.`),o.join(`
2
+ `)}exports.CORTEX_AI_BUILD_SESSION_SETTING_KEY=m;exports.CORTEX_AI_SITE_BRIEF_SETTING_KEY=c;exports.cortexBuildSessionSchema=h;exports.cortexSiteBriefInputSchema=g;exports.cortexSiteBriefSchema=r;exports.formatCortexSiteBriefForPrompt=z;exports.isCortexBuildSessionUsable=f;exports.isCortexSiteBriefComplete=x;exports.safeParseCortexSiteBrief=_;
@@ -146,6 +146,15 @@ export declare const cortexBuildSessionSchema: z.ZodObject<{
146
146
  export type CortexBuildSession = z.infer<typeof cortexBuildSessionSchema>;
147
147
  /** Parse a stored brief leniently: an unreadable row is treated as "no brief". */
148
148
  export declare function safeParseCortexSiteBrief(value: unknown): CortexSiteBrief | null;
149
+ /**
150
+ * A brief counts as collected once it names the business AND says what it does.
151
+ *
152
+ * The schema only requires the name (a chat interview saves after every answer, so a
153
+ * name-only brief is a normal intermediate state). Everything that decides whether the
154
+ * site builder may skip the interview — the chat kickoff, the wizard's "Brief saved"
155
+ * card and the route's system prompt — must agree, so they all call this one predicate.
156
+ */
157
+ export declare function isCortexSiteBriefComplete(brief: CortexSiteBrief | null | undefined): brief is CortexSiteBrief;
149
158
  /** A build session is only usable by the admin who opened it, and only until it expires. */
150
159
  export declare function isCortexBuildSessionUsable(session: CortexBuildSession | null | undefined, params: {
151
160
  actorUserId: string | null | undefined;
@@ -1,6 +1,6 @@
1
1
  import "./zod-config.es.js";
2
2
  import { z as e } from "zod";
3
- const d = "cortex_ai_site_brief", h = "cortex_ai_build_session", r = e.string().trim().min(2).max(10), c = e.strictObject({
3
+ const g = "cortex_ai_site_brief", h = "cortex_ai_build_session", r = e.string().trim().min(2).max(10), c = e.strictObject({
4
4
  purpose: e.string().trim().max(600).optional().describe("What this page is for and what a visitor should do there."),
5
5
  sections: e.array(e.string().trim().min(1).max(200)).max(20).optional().describe('Planned sections, top to bottom, e.g. ["hero", "services", "testimonials", "contact form"].'),
6
6
  slug: e.string().trim().min(1).max(120).describe('URL slug in the primary language, e.g. "home", "services", "contact".'),
@@ -56,13 +56,16 @@ function y(t) {
56
56
  const o = l.safeParse(t);
57
57
  return o.success ? o.data : null;
58
58
  }
59
- function f(t, o) {
59
+ function f(t) {
60
+ return !!(t && t.business_name.trim() && t.description?.trim());
61
+ }
62
+ function $(t, o) {
60
63
  if (!t || !o.actorUserId || t.actorUserId !== o.actorUserId)
61
64
  return !1;
62
65
  const i = Date.parse(t.expiresAt), n = (o.now ?? /* @__PURE__ */ new Date()).getTime();
63
66
  return Number.isFinite(i) && i > n;
64
67
  }
65
- function $(t) {
68
+ function b(t) {
66
69
  const o = [
67
70
  `Business: ${t.business_name}${t.tagline ? ` — ${t.tagline}` : ""}`
68
71
  ];
@@ -99,11 +102,12 @@ function $(t) {
99
102
  }
100
103
  export {
101
104
  h as CORTEX_AI_BUILD_SESSION_SETTING_KEY,
102
- d as CORTEX_AI_SITE_BRIEF_SETTING_KEY,
105
+ g as CORTEX_AI_SITE_BRIEF_SETTING_KEY,
103
106
  x as cortexBuildSessionSchema,
104
107
  _ as cortexSiteBriefInputSchema,
105
108
  l as cortexSiteBriefSchema,
106
- $ as formatCortexSiteBriefForPrompt,
107
- f as isCortexBuildSessionUsable,
109
+ b as formatCortexSiteBriefForPrompt,
110
+ $ as isCortexBuildSessionUsable,
111
+ f as isCortexSiteBriefComplete,
108
112
  y as safeParseCortexSiteBrief
109
113
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextblock-cms/cortex",
3
- "version": "0.18.1",
3
+ "version": "0.18.3",
4
4
  "license": "AGPL-3.0-or-later",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -28,9 +28,9 @@
28
28
  },
29
29
  "dependencies": {
30
30
  "@ai-sdk/openai-compatible": "^2.0.42",
31
- "@nextblock-cms/db": "^0.18.1",
32
- "@nextblock-cms/ecommerce": "npm:@nextblock-cms/ecom@^0.18.1",
33
- "@nextblock-cms/utils": "^0.18.1",
31
+ "@nextblock-cms/db": "^0.18.3",
32
+ "@nextblock-cms/ecommerce": "npm:@nextblock-cms/ecom@^0.18.3",
33
+ "@nextblock-cms/utils": "^0.18.3",
34
34
  "ai": "^6.0.170",
35
35
  "zod": "^4.3.6"
36
36
  },