@@ -18,6 +18,106 @@ const languageMapping: { [key: string]: string } = {
1818 'js' : 'javascript'
1919} ;
2020
21+ export class Cvb {
22+ private content : string ;
23+ private metadata : Record < string , string > ;
24+ private files : Record < string , string > ;
25+
26+ constructor ( cvbContent : string ) {
27+ const { cvbContent : content , metadata, files } = this . parse ( cvbContent ) ;
28+ this . content = content ;
29+ this . metadata = metadata ;
30+ this . files = files ;
31+ }
32+
33+ getMetadata ( ) : Record < string , string > {
34+ return this . metadata ;
35+ }
36+
37+ getFiles ( ) : Record < string , string > {
38+ return this . files ;
39+ }
40+
41+ getUserRequest ( ) : string {
42+ return this . metadata [ '@用户需求' ] || '' ;
43+ }
44+
45+ getTimestamp ( ) : string {
46+ return this . metadata [ '@时间戳' ] || '' ;
47+ }
48+
49+ toString ( ) : string {
50+ return this . content ;
51+ }
52+
53+ private parse ( cvbContent : string ) : {
54+ cvbContent : string ;
55+ metadata : Record < string , string > ;
56+ files : Record < string , string > ;
57+ } {
58+ // 匹配## BEGIN_CVB在行首的位置
59+ const cvbStartRegex = / ^ # # B E G I N _ C V B ( \s | $ ) / m;
60+ const cvbStartMatch = cvbStartRegex . exec ( cvbContent ) ;
61+ if ( ! cvbStartMatch ) {
62+ throw new Error ( 'Invalid CVB format: missing BEGIN_CVB marker.' ) ;
63+ }
64+ const cvbStartIndex = cvbStartMatch . index ;
65+
66+ // 匹配## END_CVB在行首的位置
67+ const cvbEndRegex = / ^ # # E N D _ C V B ( \s | $ ) / m;
68+ const cvbEndMatch = cvbEndRegex . exec ( cvbContent ) ;
69+ if ( ! cvbEndMatch ) {
70+ throw new Error ( 'Invalid CVB format: missing END_CVB marker.' ) ;
71+ }
72+ const cvbEndIndex = cvbEndMatch . index ;
73+
74+ // 提取CVB内容,包括## BEGIN_CVB和## END_CVB
75+ const cvbContentStr = cvbContent . slice ( cvbStartIndex , cvbEndIndex + cvbEndMatch [ 0 ] . length ) ;
76+
77+ // 提取元数据部分
78+ const metaRegex = / ^ # # M E T A \n ( [ \s \S ] * ?) ^ # # E N D _ M E T A ( \s | $ ) / m;
79+ const metaMatch = metaRegex . exec ( cvbContentStr ) ;
80+ if ( ! metaMatch ) {
81+ throw new Error ( 'Invalid CVB format: missing META section.' ) ;
82+ }
83+ const metadata : Record < string , string > = { } ;
84+ const metaContent = metaMatch [ 1 ] . trim ( ) . split ( '\n' ) ;
85+ metaContent . forEach ( line => {
86+ const parts = line . split ( ':' ) ;
87+ if ( parts . length >= 2 ) {
88+ const key = parts . shift ( ) ?. trim ( ) ;
89+ const value = parts . join ( ':' ) . trim ( ) ;
90+ if ( key ) {
91+ metadata [ key ] = value ;
92+ }
93+ }
94+ } ) ;
95+
96+ // 提取文件内容部分
97+ const files : Record < string , string > = { } ;
98+ const fileRegex = / ^ # # F I L E : ( .* ?) \n ( [ \s \S ] * ?) (? = ^ # # F I L E : | ^ # # E N D _ C V B ) / gm;
99+ let match : RegExpExecArray | null ;
100+
101+ while ( ( match = fileRegex . exec ( cvbContentStr ) ) !== null ) {
102+ const filePath = match [ 1 ] ;
103+ let fileContent = match [ 2 ] . trim ( ) ;
104+ // 去除代码块标记
105+ const codeBlockRegex = / ^ ` ` ` .* \n ( [ \s \S ] * ?) \n ` ` ` $ / m;
106+ const codeBlockMatch = codeBlockRegex . exec ( fileContent ) ;
107+ if ( codeBlockMatch ) {
108+ fileContent = codeBlockMatch [ 1 ] ;
109+ }
110+ files [ filePath ] = fileContent ;
111+ }
112+
113+ return {
114+ cvbContent : cvbContentStr ,
115+ metadata,
116+ files,
117+ } ;
118+ }
119+ }
120+
21121/**
22122 * 返回 CVB 格式介绍的静态字符串
23123 * @returns CVB 格式介绍
@@ -162,78 +262,6 @@ export async function generateCvb(filePaths: string[], userRequest: string): Pro
162262 return cvbFilePath ;
163263}
164264
165- /**
166- * 解析 CVB 格式内容
167- * @param cvbContent CVB 内容
168- * @returns 包含 CVB 字符串、元数据和文件内容的对象
169- */
170- export function parseCvb ( cvbContent : string ) : {
171- cvbContent : string ;
172- metadata : Record < string , string > ;
173- files : Record < string , string > ;
174- } {
175- // 匹配## BEGIN_CVB在行首的位置
176- const cvbStartRegex = / ^ # # B E G I N _ C V B ( \s | $ ) / m;
177- const cvbStartMatch = cvbStartRegex . exec ( cvbContent ) ;
178- if ( ! cvbStartMatch ) {
179- throw new Error ( 'Invalid CVB format: missing BEGIN_CVB marker.' ) ;
180- }
181- const cvbStartIndex = cvbStartMatch . index ;
182-
183- // 匹配## END_CVB在行首的位置
184- const cvbEndRegex = / ^ # # E N D _ C V B ( \s | $ ) / m;
185- const cvbEndMatch = cvbEndRegex . exec ( cvbContent ) ;
186- if ( ! cvbEndMatch ) {
187- throw new Error ( 'Invalid CVB format: missing END_CVB marker.' ) ;
188- }
189- const cvbEndIndex = cvbEndMatch . index ;
190-
191- // 提取CVB内容,包括## BEGIN_CVB和## END_CVB
192- const cvbContentStr = cvbContent . slice ( cvbStartIndex , cvbEndIndex + cvbEndMatch [ 0 ] . length ) ;
193-
194- // 提取元数据部分
195- const metaRegex = / ^ # # M E T A \n ( [ \s \S ] * ?) ^ # # E N D _ M E T A ( \s | $ ) / m;
196- const metaMatch = metaRegex . exec ( cvbContentStr ) ;
197- if ( ! metaMatch ) {
198- throw new Error ( 'Invalid CVB format: missing META section.' ) ;
199- }
200- const metadata : Record < string , string > = { } ;
201- const metaContent = metaMatch [ 1 ] . trim ( ) . split ( '\n' ) ;
202- metaContent . forEach ( line => {
203- const parts = line . split ( ':' ) ;
204- if ( parts . length >= 2 ) {
205- const key = parts . shift ( ) ?. trim ( ) ;
206- const value = parts . join ( ':' ) . trim ( ) ;
207- if ( key ) {
208- metadata [ key ] = value ;
209- }
210- }
211- } ) ;
212-
213- // 提取文件内容部分
214- const files : Record < string , string > = { } ;
215- const fileRegex = / ^ # # F I L E : ( .* ?) \n ( [ \s \S ] * ?) (? = ^ # # F I L E : | ^ # # E N D _ C V B ) / gm;
216- let match : RegExpExecArray | null ;
217-
218- while ( ( match = fileRegex . exec ( cvbContentStr ) ) !== null ) {
219- const filePath = match [ 1 ] ;
220- let fileContent = match [ 2 ] . trim ( ) ;
221- // 去除代码块标记
222- const codeBlockRegex = / ^ ` ` ` .* \n ( [ \s \S ] * ?) \n ` ` ` $ / m;
223- const codeBlockMatch = codeBlockRegex . exec ( fileContent ) ;
224- if ( codeBlockMatch ) {
225- fileContent = codeBlockMatch [ 1 ] ;
226- }
227- files [ filePath ] = fileContent ;
228- }
229-
230- return {
231- cvbContent : cvbContentStr ,
232- metadata,
233- files,
234- } ;
235- }
236-
237265/**
238266 * 将 CVB 文件内容应用到当前工作目录
239267 * @param cvbContent CVB 文件内容
@@ -247,7 +275,8 @@ export function applyCvbToWorkspace(cvbContent: string): void {
247275 const workspacePath = workspaceFolders [ 0 ] . uri . fsPath ;
248276
249277 // 解析 CVB 文件内容
250- const { files } = parseCvb ( cvbContent ) ;
278+ const cvb = new Cvb ( cvbContent ) ;
279+ const files = cvb . getFiles ( ) ;
251280
252281 // 遍历文件内容
253282 for ( const [ filePath , fileContent ] of Object . entries ( files ) ) {
0 commit comments