legends810/testingnew
0
1import type { Message } from 'ai';2import { generateId } from './fileUtils';3 4export interface ProjectCommands {5 type: string;6 setupCommand?: string;7 startCommand?: string;8 followupMessage: string;9}10 11interface FileContent {12 content: string;13 path: string;14}15 16export async function detectProjectCommands(files: FileContent[]): Promise<ProjectCommands> {17 const hasFile = (name: string) => files.some((f) => f.path.endsWith(name));18 19 if (hasFile('package.json')) {20 const packageJsonFile = files.find((f) => f.path.endsWith('package.json'));21 22 if (!packageJsonFile) {23 return { type: '', setupCommand: '', followupMessage: '' };24 }25 26 try {27 const packageJson = JSON.parse(packageJsonFile.content);28 const scripts = packageJson?.scripts || {};29 30 // Check for preferred commands in priority order31 const preferredCommands = ['dev', 'start', 'preview'];32 const availableCommand = preferredCommands.find((cmd) => scripts[cmd]);33 34 if (availableCommand) {35 return {36 type: 'Node.js',37 setupCommand: `npm install`,38 startCommand: `npm run ${availableCommand}`,39 followupMessage: `Found "${availableCommand}" script in package.json. Running "npm run ${availableCommand}" after installation.`,40 };41 }42 43 return {44 type: 'Node.js',45 setupCommand: 'npm install',46 followupMessage:47 'Would you like me to inspect package.json to determine the available scripts for running this project?',48 };49 } catch (error) {50 console.error('Error parsing package.json:', error);51 return { type: '', setupCommand: '', followupMessage: '' };52 }53 }54 55 if (hasFile('index.html')) {56 return {57 type: 'Static',58 startCommand: 'npx --yes serve',59 followupMessage: '',60 };61 }62 63 return { type: '', setupCommand: '', followupMessage: '' };64}65 66export function createCommandsMessage(commands: ProjectCommands): Message | null {67 if (!commands.setupCommand && !commands.startCommand) {68 return null;69 }70 71 let commandString = '';72 73 if (commands.setupCommand) {74 commandString += `75<boltAction type="shell">${commands.setupCommand}</boltAction>`;76 }77 78 if (commands.startCommand) {79 commandString += `80<boltAction type="start">${commands.startCommand}</boltAction>81`;82 }83 84 return {85 role: 'assistant',86 content: `87<boltArtifact id="project-setup" title="Project Setup">88${commandString}89</boltArtifact>${commands.followupMessage ? `\n\n${commands.followupMessage}` : ''}`,90 id: generateId(),91 createdAt: new Date(),92 };93}94 95export function escapeBoltArtifactTags(input: string) {96 // Regular expression to match boltArtifact tags and their content97 const regex = /(<boltArtifact[^>]*>)([\s\S]*?)(<\/boltArtifact>)/g;98 99 return input.replace(regex, (match, openTag, content, closeTag) => {100 // Escape the opening tag101 const escapedOpenTag = openTag.replace(/</g, '<').replace(/>/g, '>');102 103 // Escape the closing tag104 const escapedCloseTag = closeTag.replace(/</g, '<').replace(/>/g, '>');105 106 // Return the escaped version107 return `${escapedOpenTag}${content}${escapedCloseTag}`;108 });109}110 111export function escapeBoltAActionTags(input: string) {112 // Regular expression to match boltArtifact tags and their content113 const regex = /(<boltAction[^>]*>)([\s\S]*?)(<\/boltAction>)/g;114 115 return input.replace(regex, (match, openTag, content, closeTag) => {116 // Escape the opening tag117 const escapedOpenTag = openTag.replace(/</g, '<').replace(/>/g, '>');118 119 // Escape the closing tag120 const escapedCloseTag = closeTag.replace(/</g, '<').replace(/>/g, '>');121 122 // Return the escaped version123 return `${escapedOpenTag}${content}${escapedCloseTag}`;124 });125}126 127export function escapeBoltTags(input: string) {128 return escapeBoltArtifactTags(escapeBoltAActionTags(input));129}130 