@c0-ui/protocol 0.1.0
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/LICENSE +21 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/parser.d.ts +30 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +274 -0
- package/dist/parser.js.map +1 -0
- package/dist/serializer.d.ts +17 -0
- package/dist/serializer.d.ts.map +1 -0
- package/dist/serializer.js +59 -0
- package/dist/serializer.js.map +1 -0
- package/dist/tags.d.ts +40 -0
- package/dist/tags.d.ts.map +1 -0
- package/dist/tags.js +81 -0
- package/dist/tags.js.map +1 -0
- package/dist/types.d.ts +60 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +32 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 c0 contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type { ArtifactMeta, ArtifactPart, ContentPart, CustomMarkdownPart, MessagePart, ParsedResponse, StreamParser, StreamParserOptions, ThinkItem, } from './types.js';
|
|
2
|
+
export { createStreamParser, parseResponse } from './parser.js';
|
|
3
|
+
export { extractContext, serializeResponse } from './serializer.js';
|
|
4
|
+
export { escapeXml, TAGS, unescapeXml, wrapArtifact, wrapArtifactDiff, wrapContent, wrapContext, wrapCustomMarkdown, wrapThinkItem, } from './tags.js';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,cAAc,EACd,YAAY,EACZ,mBAAmB,EACnB,SAAS,GACV,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGhE,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAGpE,OAAO,EACL,SAAS,EACT,IAAI,EACJ,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,aAAa,GACd,MAAM,WAAW,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Parser
|
|
2
|
+
export { createStreamParser, parseResponse } from './parser.js';
|
|
3
|
+
// Serializer
|
|
4
|
+
export { extractContext, serializeResponse } from './serializer.js';
|
|
5
|
+
// Tag builders
|
|
6
|
+
export { escapeXml, TAGS, unescapeXml, wrapArtifact, wrapArtifactDiff, wrapContent, wrapContext, wrapCustomMarkdown, wrapThinkItem, } from './tags.js';
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,SAAS;AACT,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEhE,aAAa;AACb,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpE,eAAe;AACf,OAAO,EACL,SAAS,EACT,IAAI,EACJ,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,aAAa,GACd,MAAM,WAAW,CAAC"}
|
package/dist/parser.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Streaming XML-DSL parser for c0.
|
|
3
|
+
*
|
|
4
|
+
* Reverse-engineered from C1's xmlParser-B5C8tiiX.js.
|
|
5
|
+
* Uses htmlparser2 in XML mode for incremental parsing,
|
|
6
|
+
* and immer for immutable state updates on each chunk.
|
|
7
|
+
*/
|
|
8
|
+
import type { ParsedResponse, StreamParser, StreamParserOptions } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Create a streaming XML-DSL parser.
|
|
11
|
+
*
|
|
12
|
+
* Call `write(chunk)` for each streamed chunk.
|
|
13
|
+
* Call `getResult()` at any time to get the current parsed state.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* const parser = createStreamParser();
|
|
18
|
+
* parser.write('<content thesys="true">Hello');
|
|
19
|
+
* parser.write(' world</content>');
|
|
20
|
+
* const result = parser.getResult();
|
|
21
|
+
* // result.parts[0] = { type: 'content', data: 'Hello world' }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare function createStreamParser(options?: StreamParserOptions): StreamParser;
|
|
25
|
+
/**
|
|
26
|
+
* Parse a complete XML-DSL string in one shot.
|
|
27
|
+
* Convenience wrapper for non-streaming use cases.
|
|
28
|
+
*/
|
|
29
|
+
export declare function parseResponse(xml: string): ParsedResponse;
|
|
30
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAKV,cAAc,EAEd,YAAY,EACZ,mBAAmB,EAGpB,MAAM,YAAY,CAAC;AAuNpB;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,YAAY,CAkE9E;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAIzD"}
|
package/dist/parser.js
ADDED
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Streaming XML-DSL parser for c0.
|
|
3
|
+
*
|
|
4
|
+
* Reverse-engineered from C1's xmlParser-B5C8tiiX.js.
|
|
5
|
+
* Uses htmlparser2 in XML mode for incremental parsing,
|
|
6
|
+
* and immer for immutable state updates on each chunk.
|
|
7
|
+
*/
|
|
8
|
+
import { Parser } from 'htmlparser2';
|
|
9
|
+
import { produce } from 'immer';
|
|
10
|
+
// ─── Initial State ────────────────────────────────────────
|
|
11
|
+
function initialState() {
|
|
12
|
+
return {
|
|
13
|
+
currentTag: undefined,
|
|
14
|
+
parts: [],
|
|
15
|
+
think: [],
|
|
16
|
+
context: '',
|
|
17
|
+
isContentClosed: false,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
// ─── Index Helpers ────────────────────────────────────────
|
|
21
|
+
function findContentIndex(parts) {
|
|
22
|
+
return parts.findIndex((p) => p.type === 'content');
|
|
23
|
+
}
|
|
24
|
+
function findLastArtifactIndex(parts) {
|
|
25
|
+
for (let i = parts.length - 1; i >= 0; i--) {
|
|
26
|
+
if (parts[i].type === 'artifact')
|
|
27
|
+
return i;
|
|
28
|
+
}
|
|
29
|
+
return -1;
|
|
30
|
+
}
|
|
31
|
+
function findLastCustomMarkdownIndex(parts) {
|
|
32
|
+
for (let i = parts.length - 1; i >= 0; i--) {
|
|
33
|
+
if (parts[i].type === 'customMarkdown')
|
|
34
|
+
return i;
|
|
35
|
+
}
|
|
36
|
+
return -1;
|
|
37
|
+
}
|
|
38
|
+
// ─── Tag Open Handler ─────────────────────────────────────
|
|
39
|
+
function handleOpenTag(state, name, attrs) {
|
|
40
|
+
state.currentTag = name;
|
|
41
|
+
switch (name) {
|
|
42
|
+
case 'content': {
|
|
43
|
+
state.isContentClosed = false;
|
|
44
|
+
const idx = findContentIndex(state.parts);
|
|
45
|
+
if (idx !== -1) {
|
|
46
|
+
state.parts[idx].data = '';
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
state.parts.push({ type: 'content', data: '' });
|
|
50
|
+
}
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
case 'artifact': {
|
|
54
|
+
const id = attrs.id ?? crypto.randomUUID();
|
|
55
|
+
const version = attrs.version ? parseInt(attrs.version, 10) : 1;
|
|
56
|
+
const existingIdx = state.parts.findIndex((p) => p.type === 'artifact' && p.id === id);
|
|
57
|
+
if (existingIdx === -1) {
|
|
58
|
+
state.parts.push({
|
|
59
|
+
type: 'artifact',
|
|
60
|
+
artifactType: attrs.type || 'slides',
|
|
61
|
+
data: '',
|
|
62
|
+
diff: '',
|
|
63
|
+
version,
|
|
64
|
+
id,
|
|
65
|
+
isDiffClosed: true,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
state.parts[existingIdx].data = '';
|
|
70
|
+
}
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
case 'artifact_diff': {
|
|
74
|
+
const idx = findLastArtifactIndex(state.parts);
|
|
75
|
+
if (idx !== -1) {
|
|
76
|
+
const artifact = state.parts[idx];
|
|
77
|
+
artifact.diff = '';
|
|
78
|
+
artifact.isDiffClosed = false;
|
|
79
|
+
}
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
case 'context':
|
|
83
|
+
state.context = '';
|
|
84
|
+
break;
|
|
85
|
+
case 'thinkitem':
|
|
86
|
+
state.think.push({
|
|
87
|
+
title: '',
|
|
88
|
+
content: '',
|
|
89
|
+
ephemeral: attrs.ephemeral === 'true',
|
|
90
|
+
});
|
|
91
|
+
break;
|
|
92
|
+
case 'custommarkdown':
|
|
93
|
+
state.parts.push({
|
|
94
|
+
type: 'customMarkdown',
|
|
95
|
+
data: { content: '' },
|
|
96
|
+
});
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// ─── Text Handler ─────────────────────────────────────────
|
|
101
|
+
function handleText(state, text) {
|
|
102
|
+
switch (state.currentTag) {
|
|
103
|
+
case 'content': {
|
|
104
|
+
const idx = findContentIndex(state.parts);
|
|
105
|
+
if (idx !== -1) {
|
|
106
|
+
state.parts[idx].data += text;
|
|
107
|
+
}
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
case 'artifact': {
|
|
111
|
+
const idx = findLastArtifactIndex(state.parts);
|
|
112
|
+
if (idx !== -1) {
|
|
113
|
+
state.parts[idx].data += text;
|
|
114
|
+
}
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
case 'artifact_diff': {
|
|
118
|
+
const idx = findLastArtifactIndex(state.parts);
|
|
119
|
+
if (idx !== -1) {
|
|
120
|
+
state.parts[idx].diff += text;
|
|
121
|
+
}
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
case 'context':
|
|
125
|
+
state.context += text;
|
|
126
|
+
break;
|
|
127
|
+
case 'thinkitem':
|
|
128
|
+
// Ignore text directly inside <thinkitem> (only children matter)
|
|
129
|
+
break;
|
|
130
|
+
case 'thinkitemtitle': {
|
|
131
|
+
const item = state.think[state.think.length - 1];
|
|
132
|
+
if (item)
|
|
133
|
+
item.title += text;
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
case 'thinkitemcontent': {
|
|
137
|
+
const item = state.think[state.think.length - 1];
|
|
138
|
+
if (item)
|
|
139
|
+
item.content += text;
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
case 'custommarkdown': {
|
|
143
|
+
const idx = findLastCustomMarkdownIndex(state.parts);
|
|
144
|
+
if (idx !== -1) {
|
|
145
|
+
state.parts[idx].data.content += text;
|
|
146
|
+
}
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
default: {
|
|
150
|
+
// Text outside any known tag → treat as content
|
|
151
|
+
const idx = findContentIndex(state.parts);
|
|
152
|
+
if (idx !== -1) {
|
|
153
|
+
state.parts[idx].data += text;
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
state.parts.push({ type: 'content', data: text });
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// ─── Close Tag Handler ────────────────────────────────────
|
|
162
|
+
/** Returns the closing tag name so callers can fire callbacks */
|
|
163
|
+
function handleCloseTag(state) {
|
|
164
|
+
const closingTag = state.currentTag;
|
|
165
|
+
if (state.currentTag === 'content' ||
|
|
166
|
+
state.currentTag === 'artifact' ||
|
|
167
|
+
state.currentTag === 'artifact_diff') {
|
|
168
|
+
state.isContentClosed = true;
|
|
169
|
+
}
|
|
170
|
+
if (state.currentTag === 'artifact_diff') {
|
|
171
|
+
const idx = findLastArtifactIndex(state.parts);
|
|
172
|
+
if (idx !== -1) {
|
|
173
|
+
state.parts[idx].isDiffClosed = true;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
state.currentTag = undefined;
|
|
177
|
+
return closingTag;
|
|
178
|
+
}
|
|
179
|
+
// ─── State → Response ─────────────────────────────────────
|
|
180
|
+
function toResponse(state) {
|
|
181
|
+
return {
|
|
182
|
+
parts: state.parts,
|
|
183
|
+
think: state.think,
|
|
184
|
+
context: state.context,
|
|
185
|
+
isContentClosed: state.isContentClosed,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
// ─── Public API ───────────────────────────────────────────
|
|
189
|
+
/**
|
|
190
|
+
* Create a streaming XML-DSL parser.
|
|
191
|
+
*
|
|
192
|
+
* Call `write(chunk)` for each streamed chunk.
|
|
193
|
+
* Call `getResult()` at any time to get the current parsed state.
|
|
194
|
+
*
|
|
195
|
+
* @example
|
|
196
|
+
* ```ts
|
|
197
|
+
* const parser = createStreamParser();
|
|
198
|
+
* parser.write('<content thesys="true">Hello');
|
|
199
|
+
* parser.write(' world</content>');
|
|
200
|
+
* const result = parser.getResult();
|
|
201
|
+
* // result.parts[0] = { type: 'content', data: 'Hello world' }
|
|
202
|
+
* ```
|
|
203
|
+
*/
|
|
204
|
+
export function createStreamParser(options) {
|
|
205
|
+
let state = initialState();
|
|
206
|
+
const parser = new Parser({
|
|
207
|
+
onopentag(name, attrs) {
|
|
208
|
+
state = produce(state, (draft) => {
|
|
209
|
+
handleOpenTag(draft, name, attrs);
|
|
210
|
+
});
|
|
211
|
+
},
|
|
212
|
+
ontext(text) {
|
|
213
|
+
state = produce(state, (draft) => {
|
|
214
|
+
handleText(draft, text);
|
|
215
|
+
});
|
|
216
|
+
},
|
|
217
|
+
onclosetag() {
|
|
218
|
+
let closingTag;
|
|
219
|
+
state = produce(state, (draft) => {
|
|
220
|
+
closingTag = handleCloseTag(draft);
|
|
221
|
+
});
|
|
222
|
+
// Fire callbacks after produce() so consumers see final immutable state
|
|
223
|
+
if (options && closingTag) {
|
|
224
|
+
switch (closingTag) {
|
|
225
|
+
case 'content': {
|
|
226
|
+
const idx = findContentIndex(state.parts);
|
|
227
|
+
if (idx !== -1) {
|
|
228
|
+
options.onContent?.(state.parts[idx].data);
|
|
229
|
+
}
|
|
230
|
+
break;
|
|
231
|
+
}
|
|
232
|
+
case 'artifact': {
|
|
233
|
+
const idx = findLastArtifactIndex(state.parts);
|
|
234
|
+
if (idx !== -1) {
|
|
235
|
+
options.onArtifact?.(state.parts[idx]);
|
|
236
|
+
}
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
239
|
+
case 'thinkitemcontent': {
|
|
240
|
+
const item = state.think[state.think.length - 1];
|
|
241
|
+
if (item) {
|
|
242
|
+
options.onThink?.(item);
|
|
243
|
+
}
|
|
244
|
+
break;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
}, { xmlMode: true, decodeEntities: true });
|
|
250
|
+
return {
|
|
251
|
+
write(chunk) {
|
|
252
|
+
parser.write(chunk);
|
|
253
|
+
},
|
|
254
|
+
getResult() {
|
|
255
|
+
return toResponse(state);
|
|
256
|
+
},
|
|
257
|
+
getState() {
|
|
258
|
+
return toResponse(state);
|
|
259
|
+
},
|
|
260
|
+
reset() {
|
|
261
|
+
state = initialState();
|
|
262
|
+
},
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Parse a complete XML-DSL string in one shot.
|
|
267
|
+
* Convenience wrapper for non-streaming use cases.
|
|
268
|
+
*/
|
|
269
|
+
export function parseResponse(xml) {
|
|
270
|
+
const parser = createStreamParser();
|
|
271
|
+
parser.write(xml);
|
|
272
|
+
return parser.getResult();
|
|
273
|
+
}
|
|
274
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serialize ParsedResponse back to XML-DSL string.
|
|
3
|
+
* Useful for message storage and conversation history.
|
|
4
|
+
*
|
|
5
|
+
* Mirrors C1's serialization (function U in xmlParser).
|
|
6
|
+
*/
|
|
7
|
+
import type { ParsedResponse } from './types.js';
|
|
8
|
+
export declare function serializeResponse(response: ParsedResponse): string;
|
|
9
|
+
/**
|
|
10
|
+
* Extract context from a raw c0 response string.
|
|
11
|
+
* Returns the response without context tags and the extracted context.
|
|
12
|
+
*/
|
|
13
|
+
export declare function extractContext(raw: string): {
|
|
14
|
+
response: string;
|
|
15
|
+
context: string;
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=serializer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serializer.d.ts","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAgB,cAAc,EAAE,MAAM,YAAY,CAAC;AAU/D,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAsClE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,CAcA"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serialize ParsedResponse back to XML-DSL string.
|
|
3
|
+
* Useful for message storage and conversation history.
|
|
4
|
+
*
|
|
5
|
+
* Mirrors C1's serialization (function U in xmlParser).
|
|
6
|
+
*/
|
|
7
|
+
import { wrapArtifact, wrapArtifactDiff, wrapContent, wrapContext, wrapCustomMarkdown, wrapThinkItem, } from './tags.js';
|
|
8
|
+
export function serializeResponse(response) {
|
|
9
|
+
let result = '';
|
|
10
|
+
// Think items first (matches C1 output order)
|
|
11
|
+
for (const item of response.think) {
|
|
12
|
+
result += wrapThinkItem(item.title, item.content, item.ephemeral);
|
|
13
|
+
}
|
|
14
|
+
// Message parts
|
|
15
|
+
for (const part of response.parts) {
|
|
16
|
+
switch (part.type) {
|
|
17
|
+
case 'content':
|
|
18
|
+
result += wrapContent(part.data);
|
|
19
|
+
break;
|
|
20
|
+
case 'customMarkdown':
|
|
21
|
+
result += wrapCustomMarkdown(part.data.content);
|
|
22
|
+
break;
|
|
23
|
+
case 'artifact': {
|
|
24
|
+
const artifact = part;
|
|
25
|
+
result += wrapArtifact(artifact.data, {
|
|
26
|
+
type: artifact.artifactType,
|
|
27
|
+
id: artifact.id,
|
|
28
|
+
version: artifact.version,
|
|
29
|
+
});
|
|
30
|
+
if (artifact.diff) {
|
|
31
|
+
result += wrapArtifactDiff(artifact.diff);
|
|
32
|
+
}
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Context last
|
|
38
|
+
if (response.context) {
|
|
39
|
+
result += wrapContext(response.context);
|
|
40
|
+
}
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Extract context from a raw c0 response string.
|
|
45
|
+
* Returns the response without context tags and the extracted context.
|
|
46
|
+
*/
|
|
47
|
+
export function extractContext(raw) {
|
|
48
|
+
const openTag = '<context>';
|
|
49
|
+
const closeTag = '</context>';
|
|
50
|
+
const startIdx = raw.indexOf(openTag);
|
|
51
|
+
const endIdx = raw.indexOf(closeTag);
|
|
52
|
+
if (startIdx !== -1 && endIdx > startIdx) {
|
|
53
|
+
const response = raw.slice(0, startIdx) + raw.slice(endIdx + closeTag.length);
|
|
54
|
+
const context = raw.slice(startIdx + openTag.length, endIdx);
|
|
55
|
+
return { response, context };
|
|
56
|
+
}
|
|
57
|
+
return { response: raw, context: '' };
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=serializer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serializer.js","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,aAAa,GACd,MAAM,WAAW,CAAC;AAEnB,MAAM,UAAU,iBAAiB,CAAC,QAAwB;IACxD,IAAI,MAAM,GAAG,EAAE,CAAC;IAEhB,8CAA8C;IAC9C,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QAClC,MAAM,IAAI,aAAa,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IACpE,CAAC;IAED,gBAAgB;IAChB,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QAClC,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;YAClB,KAAK,SAAS;gBACZ,MAAM,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACjC,MAAM;YACR,KAAK,gBAAgB;gBACnB,MAAM,IAAI,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBAChD,MAAM;YACR,KAAK,UAAU,CAAC,CAAC,CAAC;gBAChB,MAAM,QAAQ,GAAG,IAAoB,CAAC;gBACtC,MAAM,IAAI,YAAY,CAAC,QAAQ,CAAC,IAAI,EAAE;oBACpC,IAAI,EAAE,QAAQ,CAAC,YAAY;oBAC3B,EAAE,EAAE,QAAQ,CAAC,EAAE;oBACf,OAAO,EAAE,QAAQ,CAAC,OAAO;iBAC1B,CAAC,CAAC;gBACH,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;oBAClB,MAAM,IAAI,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAC5C,CAAC;gBACD,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;IAED,eAAe;IACf,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;QACrB,MAAM,IAAI,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW;IAIxC,MAAM,OAAO,GAAG,WAAW,CAAC;IAC5B,MAAM,QAAQ,GAAG,YAAY,CAAC;IAC9B,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAErC,IAAI,QAAQ,KAAK,CAAC,CAAC,IAAI,MAAM,GAAG,QAAQ,EAAE,CAAC;QACzC,MAAM,QAAQ,GACZ,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC/D,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC7D,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;IAC/B,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;AACxC,CAAC"}
|
package/dist/tags.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* XML tag builders for the c0 streaming protocol.
|
|
3
|
+
*
|
|
4
|
+
* These mirror C1's internal tag format:
|
|
5
|
+
* <content thesys="true">...</content>
|
|
6
|
+
* <artifact type="..." id="..." version="...">...</artifact>
|
|
7
|
+
* <thinkitem ephemeral="true|false">
|
|
8
|
+
* <thinkitemtitle>...</thinkitemtitle>
|
|
9
|
+
* <thinkitemcontent>...</thinkitemcontent>
|
|
10
|
+
* </thinkitem>
|
|
11
|
+
* <context>...</context>
|
|
12
|
+
* <custommarkdown>...</custommarkdown>
|
|
13
|
+
*/
|
|
14
|
+
export declare const TAGS: {
|
|
15
|
+
readonly CONTENT: "content";
|
|
16
|
+
readonly ARTIFACT: "artifact";
|
|
17
|
+
readonly ARTIFACT_DIFF: "artifact_diff";
|
|
18
|
+
readonly CONTEXT: "context";
|
|
19
|
+
readonly THINK_ITEM: "thinkitem";
|
|
20
|
+
readonly THINK_TITLE: "thinkitemtitle";
|
|
21
|
+
readonly THINK_CONTENT: "thinkitemcontent";
|
|
22
|
+
readonly CUSTOM_MARKDOWN: "custommarkdown";
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Escape HTML entities for safe embedding in XML.
|
|
26
|
+
* Matches lodash/escape behavior used by C1.
|
|
27
|
+
*/
|
|
28
|
+
export declare function escapeXml(str: string): string;
|
|
29
|
+
export declare function unescapeXml(str: string): string;
|
|
30
|
+
export declare function wrapContent(text: string): string;
|
|
31
|
+
export declare function wrapArtifact(data: string, meta: {
|
|
32
|
+
type: string;
|
|
33
|
+
id: string;
|
|
34
|
+
version: number;
|
|
35
|
+
}): string;
|
|
36
|
+
export declare function wrapArtifactDiff(diff: string): string;
|
|
37
|
+
export declare function wrapContext(context: string): string;
|
|
38
|
+
export declare function wrapThinkItem(title: string, content: string, ephemeral?: boolean): string;
|
|
39
|
+
export declare function wrapCustomMarkdown(markdown: string): string;
|
|
40
|
+
//# sourceMappingURL=tags.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tags.d.ts","sourceRoot":"","sources":["../src/tags.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,eAAO,MAAM,IAAI;;;;;;;;;CASP,CAAC;AAkBX;;;GAGG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAO7C;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAO/C;AAID,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAClD,MAAM,CAMR;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,OAAc,GACxB,MAAM,CAKR;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE3D"}
|
package/dist/tags.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* XML tag builders for the c0 streaming protocol.
|
|
3
|
+
*
|
|
4
|
+
* These mirror C1's internal tag format:
|
|
5
|
+
* <content thesys="true">...</content>
|
|
6
|
+
* <artifact type="..." id="..." version="...">...</artifact>
|
|
7
|
+
* <thinkitem ephemeral="true|false">
|
|
8
|
+
* <thinkitemtitle>...</thinkitemtitle>
|
|
9
|
+
* <thinkitemcontent>...</thinkitemcontent>
|
|
10
|
+
* </thinkitem>
|
|
11
|
+
* <context>...</context>
|
|
12
|
+
* <custommarkdown>...</custommarkdown>
|
|
13
|
+
*/
|
|
14
|
+
// ─── Tag Names ────────────────────────────────────────────
|
|
15
|
+
export const TAGS = {
|
|
16
|
+
CONTENT: 'content',
|
|
17
|
+
ARTIFACT: 'artifact',
|
|
18
|
+
ARTIFACT_DIFF: 'artifact_diff',
|
|
19
|
+
CONTEXT: 'context',
|
|
20
|
+
THINK_ITEM: 'thinkitem',
|
|
21
|
+
THINK_TITLE: 'thinkitemtitle',
|
|
22
|
+
THINK_CONTENT: 'thinkitemcontent',
|
|
23
|
+
CUSTOM_MARKDOWN: 'custommarkdown',
|
|
24
|
+
};
|
|
25
|
+
// ─── Helpers ──────────────────────────────────────────────
|
|
26
|
+
function openTag(name, attrs) {
|
|
27
|
+
const attrStr = attrs
|
|
28
|
+
? ' ' + Object.entries(attrs).map(([k, v]) => `${k}="${v}"`).join(' ')
|
|
29
|
+
: '';
|
|
30
|
+
return `<${name}${attrStr}>`;
|
|
31
|
+
}
|
|
32
|
+
function closeTag(name) {
|
|
33
|
+
return `</${name}>`;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Escape HTML entities for safe embedding in XML.
|
|
37
|
+
* Matches lodash/escape behavior used by C1.
|
|
38
|
+
*/
|
|
39
|
+
export function escapeXml(str) {
|
|
40
|
+
return str
|
|
41
|
+
.replace(/&/g, '&')
|
|
42
|
+
.replace(/</g, '<')
|
|
43
|
+
.replace(/>/g, '>')
|
|
44
|
+
.replace(/"/g, '"')
|
|
45
|
+
.replace(/'/g, ''');
|
|
46
|
+
}
|
|
47
|
+
export function unescapeXml(str) {
|
|
48
|
+
return str
|
|
49
|
+
.replace(/&/g, '&')
|
|
50
|
+
.replace(/</g, '<')
|
|
51
|
+
.replace(/>/g, '>')
|
|
52
|
+
.replace(/"/g, '"')
|
|
53
|
+
.replace(/'/g, "'");
|
|
54
|
+
}
|
|
55
|
+
// ─── Tag Builders ─────────────────────────────────────────
|
|
56
|
+
export function wrapContent(text) {
|
|
57
|
+
return `${openTag(TAGS.CONTENT, { thesys: 'true' })}${escapeXml(text)}${closeTag(TAGS.CONTENT)}`;
|
|
58
|
+
}
|
|
59
|
+
export function wrapArtifact(data, meta) {
|
|
60
|
+
return `${openTag(TAGS.ARTIFACT, {
|
|
61
|
+
type: meta.type,
|
|
62
|
+
id: meta.id,
|
|
63
|
+
version: String(meta.version),
|
|
64
|
+
})}${escapeXml(data)}${closeTag(TAGS.ARTIFACT)}`;
|
|
65
|
+
}
|
|
66
|
+
export function wrapArtifactDiff(diff) {
|
|
67
|
+
return `${openTag(TAGS.ARTIFACT_DIFF)}${escapeXml(diff)}${closeTag(TAGS.ARTIFACT_DIFF)}`;
|
|
68
|
+
}
|
|
69
|
+
export function wrapContext(context) {
|
|
70
|
+
return `${openTag(TAGS.CONTEXT)}${escapeXml(context)}${closeTag(TAGS.CONTEXT)}`;
|
|
71
|
+
}
|
|
72
|
+
export function wrapThinkItem(title, content, ephemeral = true) {
|
|
73
|
+
const titleTag = `${openTag(TAGS.THINK_TITLE)}${escapeXml(title)}${closeTag(TAGS.THINK_TITLE)}`;
|
|
74
|
+
const contentTag = `${openTag(TAGS.THINK_CONTENT)}${escapeXml(content)}${closeTag(TAGS.THINK_CONTENT)}`;
|
|
75
|
+
const attrs = ephemeral ? { ephemeral: 'true' } : undefined;
|
|
76
|
+
return `${openTag(TAGS.THINK_ITEM, attrs)}${titleTag}${contentTag}${closeTag(TAGS.THINK_ITEM)}`;
|
|
77
|
+
}
|
|
78
|
+
export function wrapCustomMarkdown(markdown) {
|
|
79
|
+
return `${openTag(TAGS.CUSTOM_MARKDOWN)}${escapeXml(markdown)}${closeTag(TAGS.CUSTOM_MARKDOWN)}`;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=tags.js.map
|
package/dist/tags.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tags.js","sourceRoot":"","sources":["../src/tags.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export interface ContentPart {
|
|
2
|
+
type: 'content';
|
|
3
|
+
data: string;
|
|
4
|
+
}
|
|
5
|
+
export interface ArtifactPart {
|
|
6
|
+
type: 'artifact';
|
|
7
|
+
artifactType: string;
|
|
8
|
+
id: string;
|
|
9
|
+
version: number;
|
|
10
|
+
data: string;
|
|
11
|
+
diff: string;
|
|
12
|
+
isDiffClosed: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface CustomMarkdownPart {
|
|
15
|
+
type: 'customMarkdown';
|
|
16
|
+
data: {
|
|
17
|
+
content: string;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export type MessagePart = ContentPart | ArtifactPart | CustomMarkdownPart;
|
|
21
|
+
export interface ThinkItem {
|
|
22
|
+
title: string;
|
|
23
|
+
content: string;
|
|
24
|
+
ephemeral: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface ParsedResponse {
|
|
27
|
+
parts: MessagePart[];
|
|
28
|
+
think: ThinkItem[];
|
|
29
|
+
context: string;
|
|
30
|
+
isContentClosed: boolean;
|
|
31
|
+
}
|
|
32
|
+
export interface StreamParserOptions {
|
|
33
|
+
onArtifact?: (artifact: ArtifactPart) => void;
|
|
34
|
+
onThink?: (item: ThinkItem) => void;
|
|
35
|
+
onContent?: (content: string) => void;
|
|
36
|
+
}
|
|
37
|
+
export interface StreamParser {
|
|
38
|
+
/** Feed a chunk of XML-DSL into the parser */
|
|
39
|
+
write(chunk: string): void;
|
|
40
|
+
/** Get current parsed state (safe to call during streaming) */
|
|
41
|
+
getResult(): ParsedResponse;
|
|
42
|
+
/** Alias for getResult() */
|
|
43
|
+
getState(): ParsedResponse;
|
|
44
|
+
/** Reset parser to initial state */
|
|
45
|
+
reset(): void;
|
|
46
|
+
}
|
|
47
|
+
export interface ArtifactMeta {
|
|
48
|
+
type: string;
|
|
49
|
+
id: string;
|
|
50
|
+
version: number;
|
|
51
|
+
}
|
|
52
|
+
export type TagName = 'content' | 'artifact' | 'artifact_diff' | 'context' | 'thinkitem' | 'thinkitemtitle' | 'thinkitemcontent' | 'custommarkdown';
|
|
53
|
+
export interface ParserState {
|
|
54
|
+
currentTag: TagName | undefined;
|
|
55
|
+
parts: MessagePart[];
|
|
56
|
+
think: ThinkItem[];
|
|
57
|
+
context: string;
|
|
58
|
+
isContentClosed: boolean;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,UAAU,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3B;AAED,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,YAAY,GAAG,kBAAkB,CAAC;AAI1E,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;CACpB;AAID,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAID,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAC;IAC9C,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;IACpC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AAID,MAAM,WAAW,YAAY;IAC3B,8CAA8C;IAC9C,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,+DAA+D;IAC/D,SAAS,IAAI,cAAc,CAAC;IAC5B,4BAA4B;IAC5B,QAAQ,IAAI,cAAc,CAAC;IAC3B,oCAAoC;IACpC,KAAK,IAAI,IAAI,CAAC;CACf;AAID,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;CACjB;AAID,MAAM,MAAM,OAAO,GACf,SAAS,GACT,UAAU,GACV,eAAe,GACf,SAAS,GACT,WAAW,GACX,gBAAgB,GAChB,kBAAkB,GAClB,gBAAgB,CAAC;AAErB,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,OAAO,GAAG,SAAS,CAAC;IAChC,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,OAAO,CAAC;CAC1B"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,6DAA6D"}
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@c0-ui/protocol",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"htmlparser2": "^9.1.0",
|
|
19
|
+
"immer": "^10.1.1"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"typescript": "^5.7",
|
|
23
|
+
"vitest": "^3"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsc",
|
|
27
|
+
"dev": "tsc --watch",
|
|
28
|
+
"test": "vitest run",
|
|
29
|
+
"test:watch": "vitest",
|
|
30
|
+
"clean": "rm -rf dist"
|
|
31
|
+
}
|
|
32
|
+
}
|