@toon-ui/core 0.1.0-beta.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.
@@ -0,0 +1,3 @@
1
+ import type { ToonBlock } from './types';
2
+ export declare function extractToonBlocks(content: string): ToonBlock[];
3
+ //# sourceMappingURL=formatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../src/formatter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAIzC,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,CAO9D"}
@@ -0,0 +1,10 @@
1
+ const BLOCK_REGEX = /```toon-ui\n([\s\S]*?)```/g;
2
+ export function extractToonBlocks(content) {
3
+ return [...content.matchAll(BLOCK_REGEX)].map((match) => ({
4
+ raw: match[1].trim(),
5
+ language: 'toon-ui',
6
+ start: match.index ?? 0,
7
+ end: (match.index ?? 0) + match[0].length,
8
+ }));
9
+ }
10
+ //# sourceMappingURL=formatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatter.js","sourceRoot":"","sources":["../src/formatter.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,GAAG,4BAA4B,CAAC;AAEjD,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,OAAO,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACxD,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;QACpB,QAAQ,EAAE,SAAS;QACnB,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,CAAC;QACvB,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM;KAC1C,CAAC,CAAC,CAAC;AACN,CAAC"}
@@ -0,0 +1,7 @@
1
+ export * from './types';
2
+ export { parseToonUI, ToonSyntaxError } from './parser';
3
+ export { validateToonUI } from './validator';
4
+ export { extractToonBlocks } from './formatter';
5
+ export { createPrompt, createComponentPrompt, createSafetyPrompt, createExamplesPrompt } from './prompts';
6
+ export { createRules, createToonUI, formatSubmitMessage, formatReplyMessage } from './runtime';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAC1G,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export * from './types';
2
+ export { parseToonUI, ToonSyntaxError } from './parser';
3
+ export { validateToonUI } from './validator';
4
+ export { extractToonBlocks } from './formatter';
5
+ export { createPrompt, createComponentPrompt, createSafetyPrompt, createExamplesPrompt } from './prompts';
6
+ export { createRules, createToonUI, formatSubmitMessage, formatReplyMessage } from './runtime';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAC1G,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { type ToonDocument, type ToonErrorCode, type ValidationIssue } from './types';
2
+ export declare class ToonSyntaxError extends Error {
3
+ code: ToonErrorCode;
4
+ line: number;
5
+ column: number;
6
+ constructor(issue: ValidationIssue);
7
+ }
8
+ export declare function parseToonUI(source: string): ToonDocument;
9
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyM,KAAK,YAAY,EAAE,KAAK,aAAa,EAAiB,KAAK,eAAe,EAAE,MAAM,SAAS,CAAC;AAO5S,qBAAa,eAAgB,SAAQ,KAAK;IACxC,IAAI,EAAE,aAAa,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;gBAEH,KAAK,EAAE,eAAe;CAOnC;AA2JD,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CA2BxD"}
package/dist/parser.js ADDED
@@ -0,0 +1,179 @@
1
+ import { OFFICIAL_COMPONENT_KEYS } from './types';
2
+ export class ToonSyntaxError extends Error {
3
+ code;
4
+ line;
5
+ column;
6
+ constructor(issue) {
7
+ super(issue.message);
8
+ this.name = 'ToonSyntaxError';
9
+ this.code = issue.code;
10
+ this.line = issue.line ?? 1;
11
+ this.column = issue.column ?? 1;
12
+ }
13
+ }
14
+ const quoted = /"([^"]+)"/g;
15
+ function getIndent(line) {
16
+ return line.match(/^\s*/)?.[0].length ?? 0;
17
+ }
18
+ function getQuotedValues(input) {
19
+ return [...input.matchAll(quoted)].map((match) => match[1]);
20
+ }
21
+ function syntaxIssue(code, message, line, column = 1) {
22
+ throw new ToonSyntaxError({ code, message, line, column });
23
+ }
24
+ function basePosition(line, raw) {
25
+ return { line, column: getIndent(raw) + 1 };
26
+ }
27
+ function parseLine(content, line, column) {
28
+ if (content.startsWith('text ')) {
29
+ const [value] = getQuotedValues(content);
30
+ if (!value)
31
+ syntaxIssue('MISSING_REQUIRED_FIELD', `Line ${line}: text requires a quoted value.`, line, column);
32
+ return { type: 'text', value, line, column };
33
+ }
34
+ if (content.startsWith('badge ')) {
35
+ const [label] = getQuotedValues(content);
36
+ const variant = content.trim().split(/\s+/).at(-1);
37
+ if (!label || !variant)
38
+ syntaxIssue('MISSING_REQUIRED_FIELD', `Line ${line}: badge requires label and variant.`, line, column);
39
+ return { type: 'badge', label, variant: variant, line, column };
40
+ }
41
+ if (content.startsWith('button ')) {
42
+ const [label] = getQuotedValues(content);
43
+ const variant = content.trim().split(/\s+/)[1];
44
+ if (!label || !variant)
45
+ syntaxIssue('MISSING_REQUIRED_FIELD', `Line ${line}: button requires variant and label.`, line, column);
46
+ const replyMatch = content.match(/reply="([^"]+)"/);
47
+ const isSubmit = /\bsubmit\b/.test(content);
48
+ if (!replyMatch && !isSubmit)
49
+ syntaxIssue('MISSING_REQUIRED_FIELD', `Line ${line}: button requires reply or submit.`, line, column);
50
+ return {
51
+ type: 'button',
52
+ variant: variant,
53
+ label,
54
+ action: replyMatch ? { kind: 'reply', value: replyMatch[1] } : { kind: 'submit' },
55
+ line,
56
+ column,
57
+ };
58
+ }
59
+ if (content.startsWith('field ')) {
60
+ const tokens = content.trim().split(/\s+/);
61
+ const [label] = getQuotedValues(content);
62
+ if (tokens.length < 4 || !label)
63
+ syntaxIssue('MISSING_REQUIRED_FIELD', `Line ${line}: field requires name, type and label.`, line, column);
64
+ return {
65
+ type: 'field',
66
+ name: tokens[1],
67
+ fieldType: tokens[2],
68
+ label,
69
+ required: /\brequired\b/.test(content),
70
+ line,
71
+ column,
72
+ };
73
+ }
74
+ if (content.startsWith('card ')) {
75
+ const [title] = getQuotedValues(content);
76
+ if (!title || !content.endsWith(':'))
77
+ syntaxIssue('INVALID_SYNTAX', `Line ${line}: card requires a title and nested block.`, line, column);
78
+ return { type: 'card', title, children: [], line, column };
79
+ }
80
+ if (content.startsWith('confirm ')) {
81
+ const [title] = getQuotedValues(content);
82
+ if (!title || !content.endsWith(':'))
83
+ syntaxIssue('INVALID_SYNTAX', `Line ${line}: confirm requires a title and nested block.`, line, column);
84
+ return { type: 'confirm', title, children: [], line, column };
85
+ }
86
+ if (content.startsWith('form ')) {
87
+ const [title] = getQuotedValues(content);
88
+ if (!title || !content.endsWith(':'))
89
+ syntaxIssue('INVALID_SYNTAX', `Line ${line}: form requires a title and nested block.`, line, column);
90
+ return { type: 'form', title, children: [], line, column };
91
+ }
92
+ if (content.startsWith('list ')) {
93
+ const [title] = getQuotedValues(content);
94
+ if (!title || !content.endsWith(':'))
95
+ syntaxIssue('INVALID_SYNTAX', `Line ${line}: list requires a title and nested block.`, line, column);
96
+ return { type: 'list', title, children: [], line, column };
97
+ }
98
+ if (content.startsWith('item ')) {
99
+ const [title] = getQuotedValues(content);
100
+ if (!title || !content.endsWith(':'))
101
+ syntaxIssue('INVALID_SYNTAX', `Line ${line}: item requires a title and nested block.`, line, column);
102
+ return { type: 'item', title, children: [], line, column };
103
+ }
104
+ if (content.startsWith('alert ')) {
105
+ const parts = content.trim().split(/\s+/);
106
+ const [title] = getQuotedValues(content);
107
+ if (parts.length < 2 || !title || !content.endsWith(':'))
108
+ syntaxIssue('INVALID_SYNTAX', `Line ${line}: alert requires variant, title and nested block.`, line, column);
109
+ return { type: 'alert', variant: parts[1], title, children: [], line, column };
110
+ }
111
+ if (content.startsWith('table ')) {
112
+ const [title] = getQuotedValues(content);
113
+ if (!title || !content.endsWith(':'))
114
+ syntaxIssue('INVALID_SYNTAX', `Line ${line}: table requires a title and nested block.`, line, column);
115
+ return { type: 'table', title, columns: [], rows: [], line, column };
116
+ }
117
+ if (content.startsWith('columns:')) {
118
+ const columns = content.replace('columns:', '').split(',').map((value) => value.trim()).filter(Boolean);
119
+ return { type: 'table', title: '__columns__', columns, rows: [], line, column };
120
+ }
121
+ if (content.startsWith('row:')) {
122
+ const row = content.replace('row:', '').split(',').map((value) => value.trim());
123
+ return { type: 'table', title: '__row__', columns: [], rows: [row], line, column };
124
+ }
125
+ const keyword = content.trim().split(/\s+/)[0];
126
+ if (!OFFICIAL_COMPONENT_KEYS.includes(keyword)) {
127
+ syntaxIssue('INVALID_COMPONENT', `Line ${line}: component "${keyword}" is not allowed.`, line, column);
128
+ }
129
+ syntaxIssue('INVALID_SYNTAX', `Line ${line}: invalid ToonUI syntax.`, line, column);
130
+ }
131
+ function appendNode(parent, node) {
132
+ if (parent.type === 'document') {
133
+ parent.body.push(node);
134
+ return;
135
+ }
136
+ if ('children' in parent && Array.isArray(parent.children)) {
137
+ parent.children.push(node);
138
+ return;
139
+ }
140
+ if (parent.type === 'table') {
141
+ if (node.type !== 'table') {
142
+ syntaxIssue('INVALID_NESTING', `Line ${node.line}: tables only support columns and row entries.`, node.line, node.column);
143
+ }
144
+ if (node.title === '__columns__') {
145
+ parent.columns = node.columns;
146
+ return;
147
+ }
148
+ if (node.title === '__row__') {
149
+ parent.rows.push(node.rows[0]);
150
+ return;
151
+ }
152
+ }
153
+ syntaxIssue('INVALID_NESTING', `Line ${node.line}: cannot append ${node.type} inside ${parent.type}.`, node.line, node.column);
154
+ }
155
+ export function parseToonUI(source) {
156
+ const document = { type: 'document', body: [] };
157
+ const stack = [{ indent: -1, node: document }];
158
+ source.split(/\r?\n/).forEach((rawLine, index) => {
159
+ if (!rawLine.trim())
160
+ return;
161
+ const line = index + 1;
162
+ const indent = getIndent(rawLine);
163
+ const content = rawLine.trimEnd();
164
+ const { column } = basePosition(line, rawLine);
165
+ while (stack.length > 1 && indent <= stack.at(-1).indent) {
166
+ stack.pop();
167
+ }
168
+ const parent = stack.at(-1).node;
169
+ const node = parseLine(content.trim(), line, column);
170
+ appendNode(parent, node);
171
+ const opensBlock = content.trim().endsWith(':') && 'children' in node;
172
+ const isTable = node.type === 'table' && node.title !== '__columns__' && node.title !== '__row__';
173
+ if (opensBlock || isTable) {
174
+ stack.push({ indent, node });
175
+ }
176
+ });
177
+ return document;
178
+ }
179
+ //# 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,6 @@
1
+ import type { ToonRules } from './types';
2
+ export declare function createComponentPrompt(rules: ToonRules): string;
3
+ export declare function createSafetyPrompt(): string;
4
+ export declare function createExamplesPrompt(): string;
5
+ export declare function createPrompt(rules: ToonRules): string;
6
+ //# sourceMappingURL=prompts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAQ9D;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAS3C;AAED,wBAAgB,oBAAoB,IAAI,MAAM,CAU7C;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAgBrD"}
@@ -0,0 +1,48 @@
1
+ export function createComponentPrompt(rules) {
2
+ return [
3
+ `Allowed components: ${rules.components.join(', ')}`,
4
+ `Button variants: ${rules.buttonVariants.join(', ')}`,
5
+ `Badge variants: ${rules.badgeVariants.join(', ')}`,
6
+ `Alert variants: ${rules.alertVariants.join(', ')}`,
7
+ `Field types: ${rules.fieldTypes.join(', ')}`,
8
+ ].join('\n');
9
+ }
10
+ export function createSafetyPrompt() {
11
+ return [
12
+ 'Safety rules:',
13
+ '- Output normal markdown plus optional ```toon-ui blocks only.',
14
+ '- Never output React, HTML, CSS, JavaScript, or component JSON.',
15
+ '- Never invent components or props outside the official ToonUI catalog.',
16
+ '- Never emit raw HTML, script-like content, or arbitrary CSS.',
17
+ '- Do not execute business actions directly. UI interactions must send user intent back to the chat.',
18
+ ].join('\n');
19
+ }
20
+ export function createExamplesPrompt() {
21
+ return [
22
+ 'Example:',
23
+ '```toon-ui',
24
+ 'form "Crear producto":',
25
+ ' field name text "Nombre" required',
26
+ ' field price number "Precio" required',
27
+ ' button primary "Crear producto" submit',
28
+ '```',
29
+ ].join('\n');
30
+ }
31
+ export function createPrompt(rules) {
32
+ return [
33
+ 'You are generating ToonUI for an AI-native app.',
34
+ createComponentPrompt(rules),
35
+ '',
36
+ 'Interaction rules:',
37
+ '- Every button must include variant, label, and reply="..." or submit.',
38
+ '- Every form must include a title, fields, and a submit button.',
39
+ '- Use confirm blocks for destructive actions.',
40
+ '- Reply protocol: emit user intent through compact ui_reply messages only.',
41
+ '- Submit protocol: emit compact ui_submit payloads with intent and field values only.',
42
+ '',
43
+ createSafetyPrompt(),
44
+ '',
45
+ createExamplesPrompt(),
46
+ ].join('\n');
47
+ }
48
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,qBAAqB,CAAC,KAAgB;IACpD,OAAO;QACL,uBAAuB,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QACpD,oBAAoB,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QACrD,mBAAmB,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QACnD,mBAAmB,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QACnD,gBAAgB,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;KAC9C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO;QACL,eAAe;QACf,gEAAgE;QAChE,iEAAiE;QACjE,yEAAyE;QACzE,+DAA+D;QAC/D,qGAAqG;KACtG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,MAAM,UAAU,oBAAoB;IAClC,OAAO;QACL,UAAU;QACV,YAAY;QACZ,wBAAwB;QACxB,qCAAqC;QACrC,wCAAwC;QACxC,0CAA0C;QAC1C,KAAK;KACN,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAgB;IAC3C,OAAO;QACL,iDAAiD;QACjD,qBAAqB,CAAC,KAAK,CAAC;QAC5B,EAAE;QACF,oBAAoB;QACpB,wEAAwE;QACxE,iEAAiE;QACjE,+CAA+C;QAC/C,4EAA4E;QAC5E,uFAAuF;QACvF,EAAE;QACF,kBAAkB,EAAE;QACpB,EAAE;QACF,oBAAoB,EAAE;KACvB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { type CreateToonUIOptions, type ReplyPayload, type SubmitPayload, type ToonComponentRegistry, type ToonRules, type ToonRuntime } from './types';
2
+ export declare function createRules(): ToonRules;
3
+ export declare function formatSubmitMessage(intentOrPayload: string | SubmitPayload, values?: Record<string, string | number | boolean>): string;
4
+ export declare function formatReplyMessage(valueOrPayload: string | ReplyPayload, metadata?: Record<string, string | number | boolean>): string;
5
+ export declare function createToonUI<TComponents extends ToonComponentRegistry = ToonComponentRegistry>(options?: CreateToonUIOptions<TComponents>): ToonRuntime<TComponents>;
6
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAIA,OAAO,EAAyF,KAAK,mBAAmB,EAAE,KAAK,YAAY,EAAE,KAAK,aAAa,EAAE,KAAK,qBAAqB,EAAE,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AAM/O,wBAAgB,WAAW,IAAI,SAAS,CAQvC;AAED,wBAAgB,mBAAmB,CAAC,eAAe,EAAE,MAAM,GAAG,aAAa,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,GAAG,MAAM,CAiBvI;AAED,wBAAgB,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG,YAAY,EAAE,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAM,GAAG,MAAM,CAiB1I;AAED,wBAAgB,YAAY,CAAC,WAAW,SAAS,qBAAqB,GAAG,qBAAqB,EAAE,OAAO,GAAE,mBAAmB,CAAC,WAAW,CAAM,GAAG,WAAW,CAAC,WAAW,CAAC,CAYxK"}
@@ -0,0 +1,65 @@
1
+ import { createPrompt } from './prompts';
2
+ import { parseToonUI } from './parser';
3
+ import { validateToonUI } from './validator';
4
+ import { extractToonBlocks } from './formatter';
5
+ import { ALERT_VARIANTS, BADGE_VARIANTS, BUTTON_VARIANTS, FIELD_TYPES, OFFICIAL_COMPONENT_KEYS } from './types';
6
+ function createEventId(prefix) {
7
+ return `${prefix}_${Math.random().toString(36).slice(2, 10)}`;
8
+ }
9
+ export function createRules() {
10
+ return {
11
+ components: OFFICIAL_COMPONENT_KEYS,
12
+ buttonVariants: BUTTON_VARIANTS,
13
+ badgeVariants: BADGE_VARIANTS,
14
+ alertVariants: ALERT_VARIANTS,
15
+ fieldTypes: FIELD_TYPES,
16
+ };
17
+ }
18
+ export function formatSubmitMessage(intentOrPayload, values) {
19
+ const payload = typeof intentOrPayload === 'string'
20
+ ? {
21
+ kind: 'ui_submit',
22
+ eventId: createEventId('submit'),
23
+ source: 'form',
24
+ intent: intentOrPayload,
25
+ formTitle: intentOrPayload,
26
+ values: values ?? {},
27
+ }
28
+ : intentOrPayload;
29
+ const lines = ['ui_submit:', ` eventId: ${payload.eventId}`, ` intent: ${payload.intent}`, ` formTitle: ${payload.formTitle}`];
30
+ Object.entries(payload.values).forEach(([key, value]) => {
31
+ lines.push(` ${key}: ${JSON.stringify(value)}`);
32
+ });
33
+ return lines.join('\n');
34
+ }
35
+ export function formatReplyMessage(valueOrPayload, metadata = {}) {
36
+ const payload = typeof valueOrPayload === 'string'
37
+ ? {
38
+ kind: 'ui_reply',
39
+ eventId: createEventId('reply'),
40
+ source: 'button',
41
+ component: 'button',
42
+ value: valueOrPayload,
43
+ context: metadata,
44
+ }
45
+ : valueOrPayload;
46
+ const lines = ['ui_reply:', ` eventId: ${payload.eventId}`, ` value: ${payload.value}`, ` source: ${payload.source}`, ` component: ${payload.component}`];
47
+ Object.entries(payload.context ?? {}).forEach(([key, entry]) => {
48
+ lines.push(` ${key}: ${JSON.stringify(entry)}`);
49
+ });
50
+ return lines.join('\n');
51
+ }
52
+ export function createToonUI(options = {}) {
53
+ const rules = createRules();
54
+ return {
55
+ components: (options.components ?? {}),
56
+ prompt: createPrompt(rules),
57
+ rules,
58
+ parse: parseToonUI,
59
+ validate: validateToonUI,
60
+ extractBlocks: extractToonBlocks,
61
+ formatSubmitMessage,
62
+ formatReplyMessage,
63
+ };
64
+ }
65
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,158 @@
1
+ export declare const OFFICIAL_COMPONENT_KEYS: readonly ["text", "card", "form", "field", "button", "confirm", "list", "item", "badge", "alert", "table"];
2
+ export declare const BUTTON_VARIANTS: readonly ["primary", "secondary", "danger", "ghost", "outline"];
3
+ export declare const BADGE_VARIANTS: readonly ["success", "warning", "danger", "neutral", "info"];
4
+ export declare const ALERT_VARIANTS: readonly ["info", "success", "warning", "danger"];
5
+ export declare const FIELD_TYPES: readonly ["text", "email", "number", "password", "date", "time", "textarea", "select", "checkbox"];
6
+ export type ToonComponentKey = (typeof OFFICIAL_COMPONENT_KEYS)[number];
7
+ export type ButtonVariant = (typeof BUTTON_VARIANTS)[number];
8
+ export type BadgeVariant = (typeof BADGE_VARIANTS)[number];
9
+ export type AlertVariant = (typeof ALERT_VARIANTS)[number];
10
+ export type FieldType = (typeof FIELD_TYPES)[number];
11
+ export type SubmitValue = string | number | boolean;
12
+ export type ToonErrorCode = "INVALID_COMPONENT" | "INVALID_PROP" | "INVALID_VARIANT" | "MISSING_REQUIRED_FIELD" | "INVALID_NESTING" | "INVALID_SYNTAX" | "UNSAFE_CONTENT";
13
+ export interface BaseNode {
14
+ type: ToonComponentKey;
15
+ line: number;
16
+ column: number;
17
+ }
18
+ export interface TextNode extends BaseNode {
19
+ type: "text";
20
+ value: string;
21
+ }
22
+ export interface BadgeNode extends BaseNode {
23
+ type: "badge";
24
+ label: string;
25
+ variant: BadgeVariant;
26
+ }
27
+ export interface ButtonNode extends BaseNode {
28
+ type: "button";
29
+ variant: ButtonVariant;
30
+ label: string;
31
+ action: {
32
+ kind: "reply";
33
+ value: string;
34
+ } | {
35
+ kind: "submit";
36
+ };
37
+ }
38
+ export interface FieldNode extends BaseNode {
39
+ type: "field";
40
+ name: string;
41
+ fieldType: FieldType;
42
+ label: string;
43
+ required: boolean;
44
+ }
45
+ export interface CardNode extends BaseNode {
46
+ type: "card";
47
+ title: string;
48
+ children: ToonNode[];
49
+ }
50
+ export interface ConfirmNode extends BaseNode {
51
+ type: "confirm";
52
+ title: string;
53
+ children: ToonNode[];
54
+ }
55
+ export interface ItemNode extends BaseNode {
56
+ type: "item";
57
+ title: string;
58
+ children: ToonNode[];
59
+ }
60
+ export interface ListNode extends BaseNode {
61
+ type: "list";
62
+ title: string;
63
+ children: ItemNode[];
64
+ }
65
+ export interface AlertNode extends BaseNode {
66
+ type: "alert";
67
+ variant: AlertVariant;
68
+ title: string;
69
+ children: ToonNode[];
70
+ }
71
+ export interface TableNode extends BaseNode {
72
+ type: "table";
73
+ title: string;
74
+ columns: string[];
75
+ rows: string[][];
76
+ }
77
+ export interface FormNode extends BaseNode {
78
+ type: "form";
79
+ title: string;
80
+ children: ToonNode[];
81
+ }
82
+ export interface ToonNodeByType {
83
+ text: TextNode;
84
+ card: CardNode;
85
+ form: FormNode;
86
+ field: FieldNode;
87
+ button: ButtonNode;
88
+ confirm: ConfirmNode;
89
+ list: ListNode;
90
+ item: ItemNode;
91
+ badge: BadgeNode;
92
+ alert: AlertNode;
93
+ table: TableNode;
94
+ }
95
+ export type ToonNode = ToonNodeByType[keyof ToonNodeByType];
96
+ export interface ToonDocument {
97
+ type: "document";
98
+ body: ToonNode[];
99
+ }
100
+ export interface ToonBlock {
101
+ raw: string;
102
+ language: "toon-ui";
103
+ start: number;
104
+ end: number;
105
+ }
106
+ export interface ValidationIssue {
107
+ code: ToonErrorCode;
108
+ message: string;
109
+ line?: number;
110
+ column?: number;
111
+ }
112
+ export interface ValidationResult {
113
+ ok: boolean;
114
+ errors: ValidationIssue[];
115
+ warnings: ValidationIssue[];
116
+ }
117
+ export interface ToonRules {
118
+ components: readonly ToonComponentKey[];
119
+ buttonVariants: readonly ButtonVariant[];
120
+ badgeVariants: readonly BadgeVariant[];
121
+ alertVariants: readonly AlertVariant[];
122
+ fieldTypes: readonly FieldType[];
123
+ }
124
+ export interface ReplyPayload {
125
+ kind: "ui_reply";
126
+ eventId: string;
127
+ source: "button";
128
+ value: string;
129
+ component: "button";
130
+ line?: number;
131
+ context?: Record<string, SubmitValue>;
132
+ }
133
+ export interface SubmitPayload {
134
+ kind: "ui_submit";
135
+ eventId: string;
136
+ source: "form";
137
+ intent: string;
138
+ formTitle: string;
139
+ values: Record<string, SubmitValue>;
140
+ line?: number;
141
+ }
142
+ export type ToonComponentRegistry = Partial<{
143
+ [K in keyof ToonNodeByType]: unknown;
144
+ }>;
145
+ export interface CreateToonUIOptions<TComponents extends ToonComponentRegistry = ToonComponentRegistry> {
146
+ components?: TComponents;
147
+ }
148
+ export interface ToonRuntime<TComponents extends ToonComponentRegistry = ToonComponentRegistry> {
149
+ components: TComponents;
150
+ prompt: string;
151
+ rules: ToonRules;
152
+ parse: typeof import('./parser').parseToonUI;
153
+ validate: typeof import('./validator').validateToonUI;
154
+ extractBlocks: typeof import('./formatter').extractToonBlocks;
155
+ formatSubmitMessage: typeof import('./runtime').formatSubmitMessage;
156
+ formatReplyMessage: typeof import('./runtime').formatReplyMessage;
157
+ }
158
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,6 @@
1
+ export const OFFICIAL_COMPONENT_KEYS = ["text", "card", "form", "field", "button", "confirm", "list", "item", "badge", "alert", "table"];
2
+ export const BUTTON_VARIANTS = ["primary", "secondary", "danger", "ghost", "outline"];
3
+ export const BADGE_VARIANTS = ["success", "warning", "danger", "neutral", "info"];
4
+ export const ALERT_VARIANTS = ["info", "success", "warning", "danger"];
5
+ export const FIELD_TYPES = ["text", "email", "number", "password", "date", "time", "textarea", "select", "checkbox"];
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAU,CAAC;AAClJ,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,CAAU,CAAC;AAC/F,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAU,CAAC;AAC3F,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAU,CAAC;AAChF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,CAAU,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type ToonDocument, type ValidationResult } from './types';
2
+ export declare function validateToonUI(document: ToonDocument): ValidationResult;
3
+ //# sourceMappingURL=validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"AACA,OAAO,EAAgF,KAAK,YAAY,EAAuC,KAAK,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAsGtL,wBAAgB,cAAc,CAAC,QAAQ,EAAE,YAAY,GAAG,gBAAgB,CAIvE"}
@@ -0,0 +1,102 @@
1
+ import { z } from 'zod';
2
+ import { ALERT_VARIANTS, BADGE_VARIANTS, BUTTON_VARIANTS, FIELD_TYPES } from './types';
3
+ const buttonVariantSchema = z.enum(BUTTON_VARIANTS);
4
+ const badgeVariantSchema = z.enum(BADGE_VARIANTS);
5
+ const alertVariantSchema = z.enum(ALERT_VARIANTS);
6
+ const fieldTypeSchema = z.enum(FIELD_TYPES);
7
+ function issue(code, message, line, column) {
8
+ return { code, message, line, column };
9
+ }
10
+ function ensureNoUnsafeText(node, issues) {
11
+ if (node.type === 'text' && /<[^>]+>|\b(script|javascript:|onerror=|onclick=)\b/i.test(node.value)) {
12
+ issues.push(issue('UNSAFE_CONTENT', 'Raw HTML or script-like content is not allowed in text nodes.', node.line, node.column));
13
+ }
14
+ }
15
+ function validateFieldNode(field, issues) {
16
+ if (!field.name.trim()) {
17
+ issues.push(issue('MISSING_REQUIRED_FIELD', 'Fields must include a name.', field.line, field.column));
18
+ }
19
+ if (!field.label.trim()) {
20
+ issues.push(issue('MISSING_REQUIRED_FIELD', 'Fields must include a label.', field.line, field.column));
21
+ }
22
+ if (!fieldTypeSchema.safeParse(field.fieldType).success) {
23
+ issues.push(issue('INVALID_PROP', `Invalid field type: ${field.fieldType}`, field.line, field.column));
24
+ }
25
+ }
26
+ function visit(node, issues) {
27
+ ensureNoUnsafeText(node, issues);
28
+ switch (node.type) {
29
+ case 'button': {
30
+ if (!buttonVariantSchema.safeParse(node.variant).success) {
31
+ issues.push(issue('INVALID_VARIANT', `Invalid button variant: ${node.variant}`, node.line, node.column));
32
+ }
33
+ if (node.action.kind === 'reply' && !node.action.value.trim()) {
34
+ issues.push(issue('MISSING_REQUIRED_FIELD', 'Reply actions require a non-empty value.', node.line, node.column));
35
+ }
36
+ break;
37
+ }
38
+ case 'badge': {
39
+ if (!badgeVariantSchema.safeParse(node.variant).success) {
40
+ issues.push(issue('INVALID_VARIANT', `Invalid badge variant: ${node.variant}`, node.line, node.column));
41
+ }
42
+ break;
43
+ }
44
+ case 'alert': {
45
+ if (!alertVariantSchema.safeParse(node.variant).success) {
46
+ issues.push(issue('INVALID_VARIANT', `Invalid alert variant: ${node.variant}`, node.line, node.column));
47
+ }
48
+ node.children.forEach((child) => visit(child, issues));
49
+ break;
50
+ }
51
+ case 'field': {
52
+ validateFieldNode(node, issues);
53
+ break;
54
+ }
55
+ case 'form': {
56
+ const fields = node.children.filter((child) => child.type === 'field');
57
+ const submitButtons = node.children.filter((child) => child.type === 'button' && child.action.kind === 'submit');
58
+ if (fields.length === 0) {
59
+ issues.push(issue('MISSING_REQUIRED_FIELD', 'Forms must include at least one field.', node.line, node.column));
60
+ }
61
+ if (submitButtons.length === 0) {
62
+ issues.push(issue('MISSING_REQUIRED_FIELD', 'Forms must include a submit button.', node.line, node.column));
63
+ }
64
+ node.children.forEach((child) => visit(child, issues));
65
+ break;
66
+ }
67
+ case 'confirm':
68
+ case 'card':
69
+ case 'item': {
70
+ node.children.forEach((child) => visit(child, issues));
71
+ break;
72
+ }
73
+ case 'list': {
74
+ node.children.forEach((child) => {
75
+ if (child.type !== 'item') {
76
+ issues.push(issue('INVALID_NESTING', 'Lists can only contain item nodes.', child.line, child.column));
77
+ }
78
+ visit(child, issues);
79
+ });
80
+ break;
81
+ }
82
+ case 'table': {
83
+ if (node.columns.length === 0) {
84
+ issues.push(issue('MISSING_REQUIRED_FIELD', 'Tables must declare columns.', node.line, node.column));
85
+ }
86
+ node.rows.forEach((row, index) => {
87
+ if (row.length !== node.columns.length) {
88
+ issues.push(issue('INVALID_PROP', `Row ${index + 1} does not match column count.`, node.line, node.column));
89
+ }
90
+ });
91
+ break;
92
+ }
93
+ default:
94
+ break;
95
+ }
96
+ }
97
+ export function validateToonUI(document) {
98
+ const errors = [];
99
+ document.body.forEach((node) => visit(node, errors));
100
+ return { ok: errors.length === 0, errors, warnings: [] };
101
+ }
102
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@toon-ui/core",
3
+ "version": "0.1.0-beta.0",
4
+ "description": "Core parser, AST, validation, and protocol utilities for ToonUI.",
5
+ "keywords": ["toon-ui", "ai", "ui", "chat", "dsl", "parser"],
6
+ "homepage": "https://github.com/jefferson-lopez/toon-ui#readme",
7
+ "bugs": {
8
+ "url": "https://github.com/jefferson-lopez/toon-ui/issues"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/jefferson-lopez/toon-ui.git",
13
+ "directory": "packages/core"
14
+ },
15
+ "type": "module",
16
+ "main": "./dist/index.js",
17
+ "types": "./dist/index.d.ts",
18
+ "files": [
19
+ "dist"
20
+ ],
21
+ "publishConfig": {
22
+ "access": "public"
23
+ },
24
+ "exports": {
25
+ ".": {
26
+ "types": "./dist/index.d.ts",
27
+ "default": "./dist/index.js"
28
+ }
29
+ },
30
+ "scripts": {
31
+ "build": "tsc -p tsconfig.json",
32
+ "test": "vitest run",
33
+ "typecheck": "tsc -p tsconfig.json --noEmit",
34
+ "lint": "tsc -p tsconfig.json --noEmit"
35
+ },
36
+ "dependencies": {
37
+ "zod": "^3.23.8"
38
+ }
39
+ }