@lokascript/framework 2.3.1 → 2.5.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.
Files changed (54) hide show
  1. package/dist/api/index.js +29 -516
  2. package/dist/api/index.js.map +1 -1
  3. package/dist/core/index.js +20 -128
  4. package/dist/core/index.js.map +1 -1
  5. package/dist/core/pattern-matching/index.js +19 -12
  6. package/dist/core/pattern-matching/index.js.map +1 -1
  7. package/dist/core/tokenization/index.js.map +1 -1
  8. package/dist/core/types.d.ts +7 -354
  9. package/dist/core/types.d.ts.map +1 -1
  10. package/dist/core/types.js +21 -129
  11. package/dist/core/types.js.map +1 -1
  12. package/dist/generation/diagnostics.d.ts +5 -115
  13. package/dist/generation/diagnostics.d.ts.map +1 -1
  14. package/dist/generation/index.js +20 -77
  15. package/dist/generation/index.js.map +1 -1
  16. package/dist/index.cjs +189 -1458
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.js +108 -1347
  19. package/dist/index.js.map +1 -1
  20. package/dist/interfaces/value-extractor.d.ts +20 -0
  21. package/dist/interfaces/value-extractor.d.ts.map +1 -1
  22. package/dist/ir/explicit-parser.d.ts +2 -83
  23. package/dist/ir/explicit-parser.d.ts.map +1 -1
  24. package/dist/ir/explicit-renderer.d.ts +2 -31
  25. package/dist/ir/explicit-renderer.d.ts.map +1 -1
  26. package/dist/ir/index.js +89 -1260
  27. package/dist/ir/index.js.map +1 -1
  28. package/dist/ir/protocol-json.d.ts +2 -70
  29. package/dist/ir/protocol-json.d.ts.map +1 -1
  30. package/dist/ir/references.d.ts +2 -16
  31. package/dist/ir/references.d.ts.map +1 -1
  32. package/dist/ir/types.d.ts +2 -148
  33. package/dist/ir/types.d.ts.map +1 -1
  34. package/dist/parsing/index.js +19 -12
  35. package/dist/parsing/index.js.map +1 -1
  36. package/dist/schema/command-schema.d.ts +3 -92
  37. package/dist/schema/command-schema.d.ts.map +1 -1
  38. package/dist/schema/index.js +3 -20
  39. package/dist/schema/index.js.map +1 -1
  40. package/dist/testing/index.js +1066 -712
  41. package/dist/testing/index.js.map +1 -1
  42. package/package.json +6 -2
  43. package/src/core/types.ts +71 -600
  44. package/src/generation/diagnostics.ts +12 -233
  45. package/src/interfaces/value-extractor.ts +32 -0
  46. package/src/ir/explicit-parser.ts +12 -792
  47. package/src/ir/explicit-renderer.ts +2 -195
  48. package/src/ir/from-interchange.test.ts +91 -4
  49. package/src/ir/from-interchange.ts +59 -0
  50. package/src/ir/protocol-json.test.ts +16 -7
  51. package/src/ir/protocol-json.ts +9 -748
  52. package/src/ir/references.ts +2 -30
  53. package/src/ir/types.ts +18 -190
  54. package/src/schema/command-schema.ts +3 -134
@@ -1,239 +1,18 @@
1
1
  /**
2
2
  * Structured Error Diagnostics
3
3
  *
4
- * Framework-level diagnostic types for reporting errors, warnings, and hints
5
- * during parsing, validation, and compilation. These provide richer feedback
6
- * than simple error strings, enabling:
7
- *
8
- * - Severity levels (error, warning, info)
9
- * - Machine-readable error codes
10
- * - Source location tracking
11
- * - Actionable suggestions
12
- * - Programmatic fix lookup
13
- */
14
-
15
- // =============================================================================
16
- // Diagnostic Types
17
- // =============================================================================
18
-
19
- /**
20
- * Severity level for a diagnostic.
21
- */
22
- export type DiagnosticSeverity = 'error' | 'warning' | 'info';
23
-
24
- /**
25
- * A structured diagnostic message.
26
- *
27
- * Diagnostics provide rich error information beyond simple strings.
28
- * They're used for parser errors, validation warnings, and hints.
29
- */
30
- export interface Diagnostic {
31
- /** Human-readable message */
32
- readonly message: string;
33
-
34
- /** Severity level */
35
- readonly severity: DiagnosticSeverity;
36
-
37
- /** Machine-readable code for programmatic handling (e.g., 'parse-error', 'missing-role') */
38
- readonly code?: string;
39
-
40
- /** 1-based line number in source */
41
- readonly line?: number;
42
-
43
- /** 0-based column offset in line */
44
- readonly column?: number;
45
-
46
- /** Original source text that triggered the diagnostic */
47
- readonly source?: string;
48
-
49
- /** Actionable suggestions for fixing the issue */
50
- readonly suggestions?: readonly string[];
51
- }
52
-
53
- /**
54
- * Result of a diagnostic-aware validation.
55
- */
56
- export interface DiagnosticResult {
57
- /** Whether validation passed (no errors, though warnings/info may exist) */
58
- readonly ok: boolean;
59
-
60
- /** All diagnostics, including errors, warnings, and info */
61
- readonly diagnostics: readonly Diagnostic[];
62
-
63
- /** Convenience: count of each severity level */
64
- readonly summary: DiagnosticSummary;
65
- }
66
-
67
- /**
68
- * Summary counts by severity.
69
- */
70
- export interface DiagnosticSummary {
71
- readonly errors: number;
72
- readonly warnings: number;
73
- readonly infos: number;
74
- }
75
-
76
- // =============================================================================
77
- // Diagnostic Collector
78
- // =============================================================================
79
-
80
- /**
81
- * Collects diagnostics during a parsing/validation/compilation pass.
82
- *
83
- * Use this in your domain's validate() or parse() to accumulate
84
- * structured feedback instead of throwing on the first error.
85
- *
86
- * @example
87
- * ```typescript
88
- * const collector = createDiagnosticCollector();
89
- *
90
- * // During parsing:
91
- * collector.error('Unknown command: foo', { code: 'unknown-command', line: 3 });
92
- * collector.warning('Low confidence match', { code: 'low-confidence', line: 5 });
93
- * collector.info('Consider using "select" instead of "get"', { line: 5 });
94
- *
95
- * // Get result:
96
- * const result = collector.toResult();
97
- * // { ok: false, diagnostics: [...], summary: { errors: 1, warnings: 1, infos: 1 } }
98
- * ```
99
- */
100
- export interface DiagnosticCollector {
101
- /** Add an error diagnostic */
102
- error(message: string, options?: DiagnosticOptions): void;
103
-
104
- /** Add a warning diagnostic */
105
- warning(message: string, options?: DiagnosticOptions): void;
106
-
107
- /** Add an info diagnostic */
108
- info(message: string, options?: DiagnosticOptions): void;
109
-
110
- /** Add a diagnostic with explicit severity */
111
- add(diagnostic: Diagnostic): void;
112
-
113
- /** Whether any errors have been collected */
114
- hasErrors(): boolean;
115
-
116
- /** Get all collected diagnostics */
117
- getDiagnostics(): readonly Diagnostic[];
118
-
119
- /** Build a DiagnosticResult from collected diagnostics */
120
- toResult(): DiagnosticResult;
121
- }
122
-
123
- /**
124
- * Options for adding a diagnostic via the collector's convenience methods.
125
- */
126
- export interface DiagnosticOptions {
127
- readonly code?: string;
128
- readonly line?: number;
129
- readonly column?: number;
130
- readonly source?: string;
131
- readonly suggestions?: readonly string[];
132
- }
133
-
134
- // =============================================================================
135
- // Factory
136
- // =============================================================================
137
-
138
- /**
139
- * Create a new diagnostic collector.
4
+ * Re-exported from @lokascript/intent.
5
+ * This module is the framework's re-export point for the diagnostic types
6
+ * that live in the universal intent package.
140
7
  */
141
- export function createDiagnosticCollector(): DiagnosticCollector {
142
- const diagnostics: Diagnostic[] = [];
143
8
 
144
- function addWithSeverity(
145
- severity: DiagnosticSeverity,
146
- message: string,
147
- options?: DiagnosticOptions
148
- ): void {
149
- const diag: Diagnostic = {
150
- message,
151
- severity,
152
- ...(options?.code != null && { code: options.code }),
153
- ...(options?.line != null && { line: options.line }),
154
- ...(options?.column != null && { column: options.column }),
155
- ...(options?.source != null && { source: options.source }),
156
- ...(options?.suggestions != null &&
157
- options.suggestions.length > 0 && { suggestions: options.suggestions }),
158
- };
159
- diagnostics.push(diag);
160
- }
9
+ export type {
10
+ DiagnosticSeverity,
11
+ Diagnostic,
12
+ DiagnosticResult,
13
+ DiagnosticSummary,
14
+ DiagnosticCollector,
15
+ DiagnosticOptions,
16
+ } from '@lokascript/intent';
161
17
 
162
- return {
163
- error(message, options) {
164
- addWithSeverity('error', message, options);
165
- },
166
-
167
- warning(message, options) {
168
- addWithSeverity('warning', message, options);
169
- },
170
-
171
- info(message, options) {
172
- addWithSeverity('info', message, options);
173
- },
174
-
175
- add(diagnostic) {
176
- diagnostics.push(diagnostic);
177
- },
178
-
179
- hasErrors() {
180
- return diagnostics.some(d => d.severity === 'error');
181
- },
182
-
183
- getDiagnostics() {
184
- return diagnostics;
185
- },
186
-
187
- toResult(): DiagnosticResult {
188
- let errors = 0;
189
- let warnings = 0;
190
- let infos = 0;
191
- for (const d of diagnostics) {
192
- if (d.severity === 'error') errors++;
193
- else if (d.severity === 'warning') warnings++;
194
- else infos++;
195
- }
196
-
197
- return {
198
- ok: errors === 0,
199
- diagnostics,
200
- summary: { errors, warnings, infos },
201
- };
202
- },
203
- };
204
- }
205
-
206
- // =============================================================================
207
- // Helpers
208
- // =============================================================================
209
-
210
- /**
211
- * Create a diagnostic from an Error object.
212
- * Useful for converting caught exceptions into structured diagnostics.
213
- */
214
- export function fromError(
215
- error: unknown,
216
- options?: Omit<DiagnosticOptions, 'code'> & { code?: string }
217
- ): Diagnostic {
218
- const message = error instanceof Error ? error.message : String(error);
219
- return {
220
- message,
221
- severity: 'error',
222
- ...(options?.code != null && { code: options.code }),
223
- ...(options?.line != null && { line: options.line }),
224
- ...(options?.column != null && { column: options.column }),
225
- ...(options?.source != null && { source: options.source }),
226
- ...(options?.suggestions != null &&
227
- options.suggestions.length > 0 && { suggestions: options.suggestions }),
228
- };
229
- }
230
-
231
- /**
232
- * Filter diagnostics by severity.
233
- */
234
- export function filterBySeverity(
235
- diagnostics: readonly Diagnostic[],
236
- severity: DiagnosticSeverity
237
- ): readonly Diagnostic[] {
238
- return diagnostics.filter(d => d.severity === severity);
239
- }
18
+ export { createDiagnosticCollector, fromError, filterBySeverity } from '@lokascript/intent';
@@ -316,6 +316,38 @@ export class UnicodeIdentifierExtractor implements ValueExtractor {
316
316
  }
317
317
  }
318
318
 
319
+ /**
320
+ * Latin Extended identifier extractor — handles Latin-script languages with
321
+ * diacritics (Spanish ñ/á/é/í/ó/ú; French é/à/ù/ç; Turkish ç/ş/ı/ü/ğ/ö;
322
+ * Portuguese ã/õ; German ä/ö/ü/ß; etc).
323
+ *
324
+ * Use this in addition to (or instead of) the default `IdentifierExtractor`
325
+ * for any tokenizer whose language is Latin-script and may contain diacritic
326
+ * characters in identifiers. Without it, words like `añadir` tokenize as
327
+ * `["a", "ñadir"]` because the default ASCII extractor stops at `ñ` and the
328
+ * Unicode extractor only kicks in when a token *starts* with a non-ASCII
329
+ * character.
330
+ *
331
+ * Matches contiguous runs of `/[\p{L}\p{N}_-]/u` — any Unicode letter or
332
+ * number, plus underscore and hyphen.
333
+ */
334
+ export class LatinExtendedIdentifierExtractor implements ValueExtractor {
335
+ readonly name = 'latin-extended-identifier';
336
+
337
+ canExtract(input: string, position: number): boolean {
338
+ return /\p{L}/u.test(input[position]);
339
+ }
340
+
341
+ extract(input: string, position: number): ExtractionResult | null {
342
+ let end = position;
343
+ while (end < input.length && /[\p{L}\p{N}_-]/u.test(input[end])) {
344
+ end++;
345
+ }
346
+ if (end === position) return null;
347
+ return { value: input.slice(position, end), length: end - position };
348
+ }
349
+ }
350
+
319
351
  /**
320
352
  * Whitespace extractor - handles spaces, tabs, newlines.
321
353
  */