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.
- package/dist/index.js +8 -14
- package/package.json +1 -1
- package/templates/css/storykeep.css +1 -92872
- package/templates/src/components/compositor/Compositor.tsx +14 -6
- package/templates/src/components/compositor/Node.tsx +42 -2
- package/templates/src/components/compositor/nodes/Pane.tsx +0 -5
- package/templates/src/components/compositor/nodes/tagElements/NodeBasicTag.tsx +2 -1
- package/templates/src/components/edit/pane/AddPanePanel.tsx +5 -1
- package/templates/src/components/edit/pane/AddPanePanel_new.tsx +140 -116
- package/templates/src/components/edit/pane/AiPaneGenerator.tsx +575 -0
- package/templates/src/components/edit/pane/AiPanePreview.tsx +107 -0
- package/templates/src/components/edit/pane/PageGenSelector.tsx +10 -3
- package/templates/src/constants/prompts.json +35 -40
- package/templates/src/stores/nodes.ts +18 -15
- package/templates/src/types/compositorTypes.ts +27 -13
- package/templates/src/utils/compositor/aiPaneParser.ts +613 -0
- package/templates/src/utils/compositor/allowInsert.ts +1 -3
- package/templates/src/utils/compositor/nodesHelper.ts +61 -42
- package/templates/src/utils/compositor/tailwindClasses.ts +200 -70
- package/utils/inject-files.ts +8 -14
- package/templates/src/components/edit/pane/AddPanePanel_newAICopy.tsx +0 -107
- package/templates/src/components/edit/pane/AddPanePanel_newAICopy_modal.tsx +0 -217
- package/templates/src/components/edit/pane/AddPanePanel_newCopyMode.tsx +0 -109
|
@@ -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 {
|
|
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": "
|
|
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": "
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
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": "
|
|
23
|
-
"description": "
|
|
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
|
-
"
|
|
34
|
-
"title": "
|
|
35
|
-
"description": "
|
|
17
|
+
"feature": {
|
|
18
|
+
"title": "Feature Section",
|
|
19
|
+
"description": "Describe a product feature"
|
|
36
20
|
},
|
|
37
|
-
"
|
|
21
|
+
"about": {
|
|
38
22
|
"title": "About Us",
|
|
39
|
-
"description": "
|
|
23
|
+
"description": "Company mission/values"
|
|
40
24
|
},
|
|
41
25
|
"contact": {
|
|
42
|
-
"title": "Contact
|
|
43
|
-
"description": "
|
|
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": "
|
|
51
|
-
"description": "
|
|
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
|
-
"
|
|
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
|
-
|
|
575
|
-
|
|
576
|
-
|
|
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
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
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
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
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
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
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
|