astro-tractstack 2.0.11 → 2.0.13

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.
@@ -2,20 +2,23 @@ import { useState, useMemo } from 'react';
2
2
  import { useStore } from '@nanostores/react';
3
3
  import { RadioGroup } from '@ark-ui/react/radio-group';
4
4
  import CheckCircleIcon from '@heroicons/react/20/solid/CheckCircleIcon';
5
- import CubeTransparentIcon from '@heroicons/react/24/outline/CubeTransparentIcon';
5
+ //import CubeTransparentIcon from '@heroicons/react/24/outline/CubeTransparentIcon';
6
6
  import DocumentIcon from '@heroicons/react/24/outline/DocumentIcon';
7
- //import NewspaperIcon from '@heroicons/react/24/outline/NewspaperIcon';
8
7
  import ExclamationTriangleIcon from '@heroicons/react/24/outline/ExclamationTriangleIcon';
9
8
  import AddPanePanel from './AddPanePanel';
10
9
  import PageCreationGen from './PageGen';
11
10
  import PageCreationSpecial from './PageGenSpecial';
12
- import { hasAssemblyAIStore, fullContentMapStore } from '@/stores/storykeep';
11
+ import {
12
+ /* hasAssemblyAIStore,*/ fullContentMapStore,
13
+ } from '@/stores/storykeep';
13
14
  import type { NodesContext } from '@/stores/nodes';
15
+ import type { BrandConfig } from '@/types/tractstack';
14
16
 
15
17
  interface PageCreationSelectorProps {
16
18
  nodeId: string;
17
19
  ctx: NodesContext;
18
20
  isTemplate?: boolean;
21
+ config?: BrandConfig;
19
22
  }
20
23
 
21
24
  type CreationMode = {
@@ -32,6 +35,7 @@ export const PageCreationSelector = ({
32
35
  nodeId,
33
36
  ctx,
34
37
  isTemplate = false,
38
+ config,
35
39
  }: PageCreationSelectorProps) => {
36
40
  const [selectedMode, setSelectedMode] =
37
41
  useState<CreationMode['id']>('design');
@@ -61,6 +65,7 @@ export const PageCreationSelector = ({
61
65
  icon: DocumentIcon,
62
66
  active: true,
63
67
  },
68
+ /*
64
69
  ...(hasAssemblyAIStore.get()
65
70
  ? [
66
71
  {
@@ -73,6 +78,7 @@ export const PageCreationSelector = ({
73
78
  },
74
79
  ]
75
80
  : []),
81
+ */
76
82
  ];
77
83
 
78
84
  //const featuredMode = {
@@ -134,6 +140,7 @@ export const PageCreationSelector = ({
134
140
  first={true}
135
141
  ctx={ctx}
136
142
  isStoryFragment={true}
143
+ config={config!}
137
144
  />
138
145
  );
139
146
  else if (showGen) return <PageCreationGen nodeId={nodeId} ctx={ctx} />;
@@ -1,55 +1,50 @@
1
1
  {
2
- "formatPrompt": "Create a markdown summary following this structure: Start with a ## Heading 2 containing a catchy, concise title that encapsulates the main theme. Follow with a single paragraph that provides an overall short description, setting the context for the entire piece. Create 3-5 ### Heading 3 sections, each focusing on a key aspect or subtopic of the main theme. Each heading should be followed by any appropriate number of paragraphs expanding on that subtopic. Optionally, include a #### Heading 4 subsection under one or more of the ### Heading 3 sections if there's a need to dive deeper into a specific point. This should also be followed by one or two paragraphs. Ensure all content is in pure markdown format, without any HTML tags or special formatting.",
3
- "paneFormatPrompt": "Create a markdown artifact following this structure: If appropriate start with a ## Heading 2 containing a catchy, concise title that encapsulates the main theme. Follow with a single paragraph that provides an overall short description, setting the context for the entire piece. Create a ### Heading 3 section focusing on the main theme. This heading should be followed by any appropriate number of paragraphs expanding on the topic. Optionally, include a #### Heading 4 subsection if there's a need to dive deeper into a specific point. This should also be followed by one or two paragraphs. Ensure all content is in pure markdown format, without any HTML tags or special formatting.",
4
- "contextPanePrompts": {
5
- "shortformcontext": "You are writing a focused, contextual page that needs to quickly orient and inform readers about a specific topic or concept in 500 words or less. Prioritize clarity and immediate relevance over comprehensive coverage. Use a direct, efficient writing style that frontloads key information. Keep sections brief but substantive, focusing on what readers need to know in this specific context. Maintain a helpful, straightforward tone that respects the reader's time while ensuring they grasp essential points."
6
- },
7
- "panePrompts": {
8
- "shortformcontext": "You are writing focused, contextual paragraph(s) that quickly orient and inform readers about a specific topic or concept in 50-150 words. Do not include *everything* from the raw notes. Summarize selectively to meet word length target while prioritizing clarity and immediate relevance over comprehensive coverage. Use a direct, efficient writing style that frontloads key information. Keep sections brief but substantive, focusing on what readers need to know in this specific context. Maintain a helpful, straightforward tone that respects the reader's time while ensuring they grasp essential points."
9
- },
2
+ "formatPrompt": "Format the response as markdown suitable for a single web page section. Use headings (##, ###, ####), paragraphs, bold (**text**), italics (*text*), and simple links ([text](url)). Do NOT include images, lists, blockquotes, code blocks, horizontal rules, or any complex markdown.",
10
3
  "pagePrompts": {
11
- "landing": "You are writing copy for a high-traffic internet website landing page. Write for an audience who is reading this website copy and is very interested in what it has to offer. Focus on compelling value propositions, clear benefits, and strong calls-to-action. Maintain a direct, engaging tone that builds trust and encourages conversion. Each section should naturally lead visitors toward taking action. Keep paragraphs concise and impactful.",
12
- "longform": "You are writing an in-depth, long-form blog article or content piece of up to two thousand words. Take a comprehensive, authoritative approach that demonstrates deep expertise while remaining accessible. Build your argument methodically, using a clear narrative structure that guides readers through complex ideas. Focus on delivering valuable insights and thorough analysis. Use a professional yet conversational tone that maintains reader engagement throughout the extended length. Each section should build upon previous points while introducing new dimensions of the topic.",
13
- "shortformcontext": "You are writing a focused, contextual page that needs to quickly orient and inform readers about a specific topic or concept in 500 words or less. Prioritize clarity and immediate relevance over comprehensive coverage. Use a direct, efficient writing style that frontloads key information. Keep sections brief but substantive, focusing on what readers need to know in this specific context. Maintain a helpful, straightforward tone that respects the reader's time while ensuring they grasp essential points.",
14
- "product": "You are detailing a product page for an e-commerce site. Focus on highlighting unique selling points, specifications, and benefits of the product. Use persuasive language to showcase how the product solves problems or enhances the user's life. Include clear calls-to-action towards purchasing or adding to cart. Ensure the tone is enthusiastic yet informative, with concise sections for easy scanning.",
15
- "aboutus": "You're crafting the 'About Us' page for a company website. Narrate the company's history, mission, vision, and values in a storytelling manner that resonates with visitors. Highlight key milestones, team culture, and what sets the company apart. Use a warm, approachable tone that builds trust and connection with the visitor. Include subtle calls-to-action encouraging contact or further exploration of the site.",
16
- "contact": "You are writing for a contact page that must be approachable and reassuring. Outline all available contact methods clearly - phone, email, social media, etc. Provide concise instructions or forms for inquiries, emphasizing quick responses and customer satisfaction. Use a friendly, service-oriented tone to make potential clients feel welcome and valued.",
17
- "service": "You are detailing a service page where clarity and benefit-focused content are key. Describe each service with emphasis on how it benefits the client, using case studies or testimonials if possible. Structure the content to guide the visitor from understanding the service to seeing its value, culminating in a strong call-to-action to get in touch or book a service. Keep the tone professional yet engaging.",
18
- "faq": "You're compiling an FAQ page intended to preemptively answer common questions. Write in a straightforward, informative style, addressing questions succinctly but thoroughly. Organize questions by relevance or category for ease of use. Use a tone that reassures and educates, making users feel their queries are anticipated and valued."
4
+ "landing": "Write compelling copy for a landing page section. Focus on a strong headline, clear value proposition, and a call to action. Keep paragraphs concise.",
5
+ "feature": "Describe a key feature or benefit. Use a clear heading, explain the feature, highlight its advantages, and optionally include a brief user testimonial.",
6
+ "about": "Write an 'About Us' section. Include a brief company history or mission, introduce key team members (optional), and convey company values.",
7
+ "contact": "Create a contact section. Provide essential contact information (address, phone, email), potentially include a simple contact form description (no actual form code), and mention business hours.",
8
+ "faq": "Generate a Frequently Asked Questions (FAQ) section. List common questions as headings (###) and provide clear, concise answers below each.",
9
+ "testimonial": "Write a customer testimonial section. Include a quote highlighting a positive experience, attribute it to a customer (name/company), and potentially add a brief context.",
10
+ "cta": "Craft a strong Call to Action (CTA) section. Use an urgent headline, clearly state the desired action, and provide a compelling reason to act now."
19
11
  },
20
12
  "pagePromptsDetails": {
21
13
  "landing": {
22
- "title": "High-Traffic Landing Page",
23
- "description": "Engage visitors with compelling offers and clear calls-to-action"
24
- },
25
- "longform": {
26
- "title": "In-depth long-form Post",
27
- "description": "Comprehensive, expert-driven analysis on complex topics"
28
- },
29
- "shortformcontext": {
30
- "title": "Quick Context Piece",
31
- "description": "Focused content delivering immediate clarity on specific concepts"
14
+ "title": "Landing Page",
15
+ "description": "Headline, value prop, CTA"
32
16
  },
33
- "product": {
34
- "title": "Product Detail Page",
35
- "description": "Highlighting unique features, benefits, and purchase options"
17
+ "feature": {
18
+ "title": "Feature Section",
19
+ "description": "Describe a product feature"
36
20
  },
37
- "aboutus": {
21
+ "about": {
38
22
  "title": "About Us",
39
- "description": "Our story, mission, and what makes us unique"
23
+ "description": "Company mission/values"
40
24
  },
41
25
  "contact": {
42
- "title": "Contact Us",
43
- "description": "Get in touch with us easily and confidently"
44
- },
45
- "service": {
46
- "title": "Services Overview",
47
- "description": "Explore how our services can benefit you"
26
+ "title": "Contact Info",
27
+ "description": "How to get in touch"
48
28
  },
49
29
  "faq": {
50
- "title": "Frequently Asked Questions Page",
51
- "description": "Answers to commonly asked questions"
30
+ "title": "FAQ",
31
+ "description": "Common questions & answers"
32
+ },
33
+ "testimonial": {
34
+ "title": "Testimonial",
35
+ "description": "Customer quote/story"
36
+ },
37
+ "cta": {
38
+ "title": "Call to Action",
39
+ "description": "Encourage user action"
52
40
  }
53
41
  },
54
- "contextPrompt": "Using the following contextual information - both the broad topic/purpose you want to write about and any supporting details, documentation, or reference material - I will help craft appropriate content structured for your specific page type. Please provide both your high-level goal/topic and any relevant reference material you'd like incorporated:"
42
+ "aiPaneShellPrompt": {
43
+ "system": "You are an expert web designer. Your task is to generate the structural design for a component as a single JSON object. Respond *only* with the JSON.",
44
+ "user_template": "Generate the design JSON for a component with the following characteristics:\n\nDesign Style: \"{{DESIGN_INPUT}}\"\nLayout Type: \"{{LAYOUT_TYPE}}\"\n\nCRITICAL RULES:\n1. You must respond with a JSON object with keys: `bgColour`, `parentClasses`, `defaultClasses`.\n2. The `parentClasses` value *must* be structured with our internal responsive object schema (e.g., `[ { \"mobile\": { \"px\": \"4\", \"py\": \"12\" } } ]`).\n3. The `defaultClasses` value *must* be structured with responsive keys (`mobile`, `tablet`, `desktop`) containing Tailwind class strings.\n4. Ensure the selected `bgColour` provides **high contrast** (meeting at least WCAG AA standards - 4.5:1 for normal text, 3:1 for large text) with the primary text colors defined in `defaultClasses`.\n\nEXAMPLE:\n{\n \"bgColour\": \"#050710\",\n \"parentClasses\": [\n { \"mobile\": { \"px\": \"6\", \"py\": \"24\" }, \"tablet\": { \"px\": \"8\", \"py\": \"32\" } },\n { \"mobile\": { \"mx\": \"auto\", \"maxW\": \"2xl\", \"textALIGN\": \"center\" }, \"tablet\": { \"maxW\": \"4xl\" } }\n ],\n \"defaultClasses\": {\n \"h2\": { \"mobile\": \"text-4xl font-bold tracking-tight text-white mt-4\", \"tablet\": \"text-6xl\", \"desktop\": \"text-7xl\" },\n \"p\": { \"mobile\": \"text-lg leading-8 text-gray-300 mt-6\", \"tablet\": \"text-xl\", \"desktop\": \"\" }\n }\n}"
45
+ },
46
+ "aiPaneCopyPrompt": {
47
+ "system": "You are an expert **web designer and copywriter**. Your task is to generate a single, visually compelling block of HTML content. You must ensure the content is well-written, engaging, **beautifully spaced**, and **highly readable**.",
48
+ "user_template": "Here is the design 'shell' and 'theme' (bgColour, parentClasses, and defaultClasses) you must write your HTML for. Your HTML will be placed *inside* this shell. Use the `defaultClasses` as your base theme for styling:\n{{SHELL_JSON}}\n\nNow, generate the HTML content based on these inputs:\n\nContent Prompt: \"{{COPY_INPUT}}\"\nDesign Style: **strictly for visual reference** when choosing element styles **DO NOT** include any words or concepts from the `Design Style` input in the written copy text itself.\"{{DESIGN_INPUT}}\"\nLayout Type: \"{{LAYOUT_TYPE}}\"\n\nCRITICAL RULES:\n1. You are responsible for the **inner layout and visual rhythm**. You MUST add appropriate vertical margins (e.g., `mt-4`, `mt-6`, `mt-8`) directly to any HTML block elements that *deviate* from the default spacing. **Elements must not touch.**\n2. You **MUST NOT** use `<h1>` tags. You must use `<h2>`, `<h3>`, and `<p>` tags for all text content.\n3. For responsive styles, you *must* only use `md:` and `xl:` prefixes.\n4. To make headlines pop, you MUST wrap key words in `<span>` tags with creative classes (e.g., gradient text, different colors).\n5. **All text**, even short links or phrases (like 'Learn more →'), **must** be wrapped in a block element like `<p>` or `<button>`.\n6. You MUST include at least one `<button>` tag for the primary call-to-action.\n7. Verify that **all text elements**, including text within `<span>` tags, `<button>` elements, and any elements using override classes, maintain **high contrast** (meeting at least WCAG AA standards - 4.5:1 for normal text, 3:1 for large text) against the `bgColour` provided in the `SHELL_JSON`. **Prioritize readability above all else**.\n8. Respond *only* with the raw HTML.\n\nEXAMPLE of a good, well-spaced response:\n<h2 class=\"text-4xl font-bold tracking-tight text-white md:text-6xl\"><span class=\"bg-gradient-to-r from-purple-500 to-indigo-400 bg-clip-text text-transparent\">Own the Art.</span> Possess the Reality.</h2>\n<p class=\"mt-6 text-lg leading-8 text-gray-300 md:text-xl\">Every Sneaky Productions NFT is your key. This is where digital rarity meets tangible legacy.</p>\n<button class=\"mt-8 rounded-md bg-indigo-600 px-5 py-3 text-base font-semibold text-white shadow-sm hover:bg-indigo-500\">Secure Your Drop</button>\n<p class=\"mt-4 text-sm text-gray-400\">Learn more <span>→</span></p>"
49
+ }
55
50
  }
@@ -55,7 +55,7 @@ import { selectionStore } from '@/stores/selection';
55
55
  import type { SelectionRange, SelectionStoreState } from '@/stores/selection';
56
56
  import type { CompositorProps } from '@/components/compositor/Compositor';
57
57
 
58
- const blockedClickNodes = new Set<string>(['em', 'strong']);
58
+ const blockedClickNodes = new Set<string>(['em', 'strong', 'span']);
59
59
  export const ROOT_NODE_NAME = 'root';
60
60
  export const UNDO_REDO_HISTORY_CAPACITY = 500;
61
61
  const VERBOSE = false;
@@ -571,10 +571,11 @@ export class NodesContext {
571
571
  nodeId: string,
572
572
  offset: number
573
573
  ): { left: FlatNode; right: FlatNode | null } {
574
- console.log(`%c[_splitTextNode] CALLED`, 'color: #f59e0b;', {
575
- nodeId,
576
- offset,
577
- });
574
+ if (VERBOSE)
575
+ console.log(`%c[_splitTextNode] CALLED`, 'color: #f59e0b;', {
576
+ nodeId,
577
+ offset,
578
+ });
578
579
 
579
580
  const allNodes = new Map(this.allNodes.get());
580
581
  const parentNodes = new Map(this.parentNodes.get());
@@ -607,11 +608,12 @@ export class NodesContext {
607
608
 
608
609
  // Handle split at the beginning of the string (THE FIX)
609
610
  if (offset === 0) {
610
- console.log(
611
- `%c[_splitTextNode] OFFSET 0 DETECTED. Creating empty left node.`,
612
- 'color: #f59e0b; font-weight: bold;',
613
- { nodeId, text }
614
- );
611
+ if (VERBOSE)
612
+ console.log(
613
+ `%c[_splitTextNode] OFFSET 0 DETECTED. Creating empty left node.`,
614
+ 'color: #f59e0b; font-weight: bold;',
615
+ { nodeId, text }
616
+ );
615
617
 
616
618
  // Create a new empty node for the "left" half
617
619
  const leftNode: FlatNode = {
@@ -665,11 +667,12 @@ export class NodesContext {
665
667
  }
666
668
 
667
669
  // Standard split (offset > 0 and < text.length)
668
- console.log(
669
- `%c[_splitTextNode] Performing standard split...`,
670
- 'color: green;',
671
- { text, offset }
672
- );
670
+ if (VERBOSE)
671
+ console.log(
672
+ `%c[_splitTextNode] Performing standard split...`,
673
+ 'color: green;',
674
+ { text, offset }
675
+ );
673
676
 
674
677
  const leftText = text.substring(0, offset);
675
678
  const rightText = text.substring(offset);
@@ -340,6 +340,20 @@ export interface BeliefNode extends BaseNode {
340
340
  customValues?: string[];
341
341
  }
342
342
 
343
+ export type DefaultClassValue = {
344
+ mobile: Record<string, string>;
345
+ tablet: Record<string, string>;
346
+ desktop: Record<string, string>;
347
+ };
348
+
349
+ export type DefaultClasses = Record<string, DefaultClassValue>;
350
+
351
+ export type ResponsiveClasses = {
352
+ mobile?: Record<string, string>;
353
+ tablet?: Record<string, string>;
354
+ desktop?: Record<string, string>;
355
+ };
356
+
343
357
  export interface FlatNode extends BaseNode {
344
358
  tagName: string;
345
359
  tagNameCustom?: string;
@@ -359,19 +373,20 @@ export interface FlatNode extends BaseNode {
359
373
  desktop?: Record<string, string>;
360
374
  };
361
375
  elementCss?: string;
362
- buttonPayload?: {
363
- buttonClasses: Record<string, string[]>;
364
- buttonHoverClasses: Record<string, string[]>;
365
- callbackPayload: string;
366
- isExternalUrl?: boolean;
367
- bunnyPayload?: {
368
- t: string;
369
- videoId: string | null;
370
- slug?: string;
371
- isContext?: boolean;
372
- };
376
+ buttonPayload?: ButtonPayload;
377
+ }
378
+ export type ButtonPayload = {
379
+ buttonClasses: Record<string, string[]>;
380
+ buttonHoverClasses: Record<string, string[]>;
381
+ callbackPayload: string;
382
+ isExternalUrl?: boolean;
383
+ bunnyPayload?: {
384
+ t: string;
385
+ videoId: string | null;
386
+ slug?: string;
387
+ isContext?: boolean;
373
388
  };
374
- }
389
+ };
375
390
 
376
391
  export type TemplateNode = FlatNode & {
377
392
  id?: string;
@@ -423,7 +438,6 @@ export type LoadData = {
423
438
  };
424
439
 
425
440
  export type PageDesign = {
426
- // TODO: fix TemplatePane to allow required fn
427
441
  id: string;
428
442
  title: string;
429
443
  introDesign: any; // Will be TemplatePane