Skip to content

Commit bbae032

Browse files
authored
fix: git import issue when importing bolt on bolt (#1020)
* fix: import bolt on bolt fix * added escape on folder import * type fix
1 parent 6d4196a commit bbae032

File tree

5 files changed

+49
-7
lines changed

5 files changed

+49
-7
lines changed

app/components/chat/GitCloneButton.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import ignore from 'ignore';
22
import { useGit } from '~/lib/hooks/useGit';
33
import type { Message } from 'ai';
4-
import { detectProjectCommands, createCommandsMessage } from '~/utils/projectCommands';
4+
import { detectProjectCommands, createCommandsMessage, escapeBoltTags } from '~/utils/projectCommands';
55
import { generateId } from '~/utils/fileUtils';
66
import { useState } from 'react';
77
import { toast } from 'react-toastify';
@@ -84,7 +84,7 @@ ${fileContents
8484
.map(
8585
(file) =>
8686
`<boltAction type="file" filePath="${file.path}">
87-
${file.content}
87+
${escapeBoltTags(file.content)}
8888
</boltAction>`,
8989
)
9090
.join('\n')}

app/components/git/GitUrlImport.client.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { BaseChat } from '~/components/chat/BaseChat';
77
import { Chat } from '~/components/chat/Chat.client';
88
import { useGit } from '~/lib/hooks/useGit';
99
import { useChatHistory } from '~/lib/persistence';
10-
import { createCommandsMessage, detectProjectCommands } from '~/utils/projectCommands';
10+
import { createCommandsMessage, detectProjectCommands, escapeBoltTags } from '~/utils/projectCommands';
1111
import { LoadingOverlay } from '~/components/ui/LoadingOverlay';
1212
import { toast } from 'react-toastify';
1313

@@ -74,12 +74,12 @@ export function GitUrlImport() {
7474
const filesMessage: Message = {
7575
role: 'assistant',
7676
content: `Cloning the repo ${repoUrl} into ${workdir}
77-
<boltArtifact id="imported-files" title="Git Cloned Files" type="bundled">
77+
<boltArtifact id="imported-files" title="Git Cloned Files" type="bundled">
7878
${fileContents
7979
.map(
8080
(file) =>
8181
`<boltAction type="file" filePath="${file.path}">
82-
${file.content}
82+
${escapeBoltTags(file.content)}
8383
</boltAction>`,
8484
)
8585
.join('\n')}

app/lib/runtime/message-parser.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ function cleanoutMarkdownSyntax(content: string) {
6464
return content;
6565
}
6666
}
67+
68+
function cleanEscapedTags(content: string) {
69+
return content.replace(/&lt;/g, '<').replace(/&gt;/g, '>');
70+
}
6771
export class StreamingMessageParser {
6872
#messages = new Map<string, MessageState>();
6973

@@ -110,6 +114,7 @@ export class StreamingMessageParser {
110114
// Remove markdown code block syntax if present and file is not markdown
111115
if (!currentAction.filePath.endsWith('.md')) {
112116
content = cleanoutMarkdownSyntax(content);
117+
content = cleanEscapedTags(content);
113118
}
114119

115120
content += '\n';
@@ -141,6 +146,7 @@ export class StreamingMessageParser {
141146

142147
if (!currentAction.filePath.endsWith('.md')) {
143148
content = cleanoutMarkdownSyntax(content);
149+
content = cleanEscapedTags(content);
144150
}
145151

146152
this._options.callbacks?.onActionStream?.({

app/utils/folderImport.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { Message } from 'ai';
22
import { generateId } from './fileUtils';
3-
import { detectProjectCommands, createCommandsMessage } from './projectCommands';
3+
import { detectProjectCommands, createCommandsMessage, escapeBoltTags } from './projectCommands';
44

55
export const createChatFromFolder = async (
66
files: File[],
@@ -42,7 +42,7 @@ export const createChatFromFolder = async (
4242
${fileArtifacts
4343
.map(
4444
(file) => `<boltAction type="file" filePath="${file.path}">
45-
${file.content}
45+
${escapeBoltTags(file.content)}
4646
</boltAction>`,
4747
)
4848
.join('\n\n')}

app/utils/projectCommands.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,39 @@ ${commands.setupCommand}
7878
createdAt: new Date(),
7979
};
8080
}
81+
82+
export function escapeBoltArtifactTags(input: string) {
83+
// Regular expression to match boltArtifact tags and their content
84+
const regex = /(<boltArtifact[^>]*>)([\s\S]*?)(<\/boltArtifact>)/g;
85+
86+
return input.replace(regex, (match, openTag, content, closeTag) => {
87+
// Escape the opening tag
88+
const escapedOpenTag = openTag.replace(/</g, '&lt;').replace(/>/g, '&gt;');
89+
90+
// Escape the closing tag
91+
const escapedCloseTag = closeTag.replace(/</g, '&lt;').replace(/>/g, '&gt;');
92+
93+
// Return the escaped version
94+
return `${escapedOpenTag}${content}${escapedCloseTag}`;
95+
});
96+
}
97+
98+
export function escapeBoltAActionTags(input: string) {
99+
// Regular expression to match boltArtifact tags and their content
100+
const regex = /(<boltAction[^>]*>)([\s\S]*?)(<\/boltAction>)/g;
101+
102+
return input.replace(regex, (match, openTag, content, closeTag) => {
103+
// Escape the opening tag
104+
const escapedOpenTag = openTag.replace(/</g, '&lt;').replace(/>/g, '&gt;');
105+
106+
// Escape the closing tag
107+
const escapedCloseTag = closeTag.replace(/</g, '&lt;').replace(/>/g, '&gt;');
108+
109+
// Return the escaped version
110+
return `${escapedOpenTag}${content}${escapedCloseTag}`;
111+
});
112+
}
113+
114+
export function escapeBoltTags(input: string) {
115+
return escapeBoltArtifactTags(escapeBoltAActionTags(input));
116+
}

0 commit comments

Comments
 (0)