dirac-browser 0.1.1

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 (67) hide show
  1. package/README.md +88 -0
  2. package/dist/chatbox.d.ts +1 -0
  3. package/dist/chatbox.js +81 -0
  4. package/dist/index.d.ts +33 -0
  5. package/dist/index.js +39 -0
  6. package/dist/runtime/braket-parser.d.ts +44 -0
  7. package/dist/runtime/braket-parser.js +208 -0
  8. package/dist/runtime/interpreter.d.ts +6 -0
  9. package/dist/runtime/interpreter.js +110 -0
  10. package/dist/runtime/parser.d.ts +11 -0
  11. package/dist/runtime/parser.js +135 -0
  12. package/dist/runtime/session.d.ts +43 -0
  13. package/dist/runtime/session.js +171 -0
  14. package/dist/tags/assign.d.ts +6 -0
  15. package/dist/tags/assign.js +32 -0
  16. package/dist/tags/call.d.ts +6 -0
  17. package/dist/tags/call.js +130 -0
  18. package/dist/tags/defvar.d.ts +6 -0
  19. package/dist/tags/defvar.js +27 -0
  20. package/dist/tags/eval.d.ts +6 -0
  21. package/dist/tags/eval.js +55 -0
  22. package/dist/tags/execute.d.ts +6 -0
  23. package/dist/tags/execute.js +45 -0
  24. package/dist/tags/expr.d.ts +8 -0
  25. package/dist/tags/expr.js +107 -0
  26. package/dist/tags/if.d.ts +6 -0
  27. package/dist/tags/if.js +46 -0
  28. package/dist/tags/llm.d.ts +6 -0
  29. package/dist/tags/llm.js +73 -0
  30. package/dist/tags/loop.d.ts +6 -0
  31. package/dist/tags/loop.js +31 -0
  32. package/dist/tags/output.d.ts +6 -0
  33. package/dist/tags/output.js +19 -0
  34. package/dist/tags/parameters.d.ts +6 -0
  35. package/dist/tags/parameters.js +63 -0
  36. package/dist/tags/subroutine.d.ts +6 -0
  37. package/dist/tags/subroutine.js +41 -0
  38. package/dist/tags/variable.d.ts +6 -0
  39. package/dist/tags/variable.js +20 -0
  40. package/dist/types/index.d.ts +76 -0
  41. package/dist/types/index.js +5 -0
  42. package/dist/utils/llm-adapter.d.ts +22 -0
  43. package/dist/utils/llm-adapter.js +91 -0
  44. package/examples/llm-reflection-test.di +18 -0
  45. package/package.json +21 -0
  46. package/src/chatbox.ts +89 -0
  47. package/src/index.ts +47 -0
  48. package/src/runtime/braket-parser.ts +234 -0
  49. package/src/runtime/interpreter.ts +129 -0
  50. package/src/runtime/parser.ts +151 -0
  51. package/src/runtime/session.ts +209 -0
  52. package/src/tags/assign.ts +37 -0
  53. package/src/tags/call.ts +166 -0
  54. package/src/tags/defvar.ts +32 -0
  55. package/src/tags/eval.ts +65 -0
  56. package/src/tags/execute.ts +52 -0
  57. package/src/tags/expr.ts +128 -0
  58. package/src/tags/if.ts +58 -0
  59. package/src/tags/llm.ts +88 -0
  60. package/src/tags/loop.ts +43 -0
  61. package/src/tags/output.ts +23 -0
  62. package/src/tags/parameters.ts +77 -0
  63. package/src/tags/subroutine.ts +52 -0
  64. package/src/tags/variable.ts +27 -0
  65. package/src/types/index.ts +103 -0
  66. package/src/utils/llm-adapter.ts +118 -0
  67. package/tsconfig.json +18 -0
package/src/tags/if.ts ADDED
@@ -0,0 +1,58 @@
1
+ /**
2
+ * <if> tag - conditional execution
3
+ * Maps to mask_tag_if in MASK
4
+ */
5
+
6
+ import type { DiracSession, DiracElement } from '../types/index.js';
7
+ import { substituteVariables, getVariable } from '../runtime/session.js';
8
+ import { integrateChildren } from '../runtime/interpreter.js';
9
+
10
+ export async function executeIf(session: DiracSession, element: DiracElement): Promise<void> {
11
+ const test = element.attributes.test;
12
+
13
+ if (!test) {
14
+ throw new Error('<if> requires test attribute');
15
+ }
16
+
17
+ const condition = evaluateCondition(session, test);
18
+
19
+ if (condition) {
20
+ await integrateChildren(session, element);
21
+ }
22
+ }
23
+
24
+ function evaluateCondition(session: DiracSession, test: string): boolean {
25
+ // Substitute variables first
26
+ const substituted = substituteVariables(session, test);
27
+
28
+ // Simple condition evaluation (can be enhanced later)
29
+ // Supports: ==, !=, <, >, <=, >=
30
+
31
+ const operators = ['==', '!=', '<=', '>=', '<', '>'];
32
+
33
+ for (const op of operators) {
34
+ const parts = substituted.split(op);
35
+ if (parts.length === 2) {
36
+ const left = parts[0].trim();
37
+ const right = parts[1].trim();
38
+
39
+ switch (op) {
40
+ case '==':
41
+ return left === right;
42
+ case '!=':
43
+ return left !== right;
44
+ case '<':
45
+ return parseFloat(left) < parseFloat(right);
46
+ case '>':
47
+ return parseFloat(left) > parseFloat(right);
48
+ case '<=':
49
+ return parseFloat(left) <= parseFloat(right);
50
+ case '>=':
51
+ return parseFloat(left) >= parseFloat(right);
52
+ }
53
+ }
54
+ }
55
+
56
+ // If no operator, treat as boolean (non-empty = true)
57
+ return substituted.trim() !== '' && substituted.trim() !== '0' && substituted.trim() !== 'false';
58
+ }
@@ -0,0 +1,88 @@
1
+ /**
2
+ * <llm> tag - Call LLM via backend service
3
+ * Browser edition - makes HTTP calls to dirac-server
4
+ */
5
+
6
+ import type { DiracSession, DiracElement } from '../types/index.js';
7
+ import { setVariable, emit } from '../runtime/session.js';
8
+
9
+ export async function executeLLM(session: DiracSession, element: DiracElement): Promise<void> {
10
+ const model = element.attributes.model || 'claude-sonnet-4-20250514';
11
+ const userPrompt = element.attributes.prompt || element.text || '';
12
+ const name = element.attributes.name;
13
+ const temperature = parseFloat(element.attributes.temperature || '0');
14
+ const maxTokens = parseInt(element.attributes['max-tokens'] || '100', 10);
15
+
16
+ if (!userPrompt) {
17
+ throw new Error('<llm> requires prompt attribute or text content');
18
+ }
19
+
20
+ // Reflect subroutines for system prompt
21
+ // Use getAvailableSubroutines from session
22
+ // (imported from ../runtime/session.js)
23
+ // @ts-ignore
24
+ const { getAvailableSubroutines } = await import('../runtime/session.js');
25
+ const subroutines = getAvailableSubroutines(session);
26
+ let systemPrompt = 'You are an expert Dirac command generator.\nAvailable subroutines:';
27
+ for (const sub of subroutines) {
28
+ systemPrompt += `\n- <${sub.name} />: ${sub.description || ''}`;
29
+ if (sub.parameters && sub.parameters.length > 0) {
30
+ systemPrompt += ' Parameters: ' + sub.parameters.map(p => `${p.name} (${p.type || 'string'})`).join(', ');
31
+ }
32
+ }
33
+ systemPrompt += '\nInstructions: Output only valid Dirac XML tags. Do not include explanations or extra text.';
34
+
35
+ // Example (optional):
36
+ // systemPrompt += '\nExample: User: Show me my inventory\nOutput: <inventory />';
37
+
38
+ // Final prompt
39
+ const prompt = systemPrompt + '\nUser: ' + userPrompt + '\nOutput:';
40
+
41
+ // Get backend URL from config
42
+ const backendUrl = session.config.llmBackendUrl || 'http://localhost:3000';
43
+
44
+ if (session.debug) {
45
+ console.error(`[LLM] Calling backend: ${backendUrl}/api/llm/complete`);
46
+ console.error(`[LLM] Model: ${model}, Prompt length: ${prompt.length}`);
47
+ }
48
+
49
+ try {
50
+ // Call backend LLM API
51
+ const response = await fetch(`${backendUrl}/api/llm/complete`, {
52
+ method: 'POST',
53
+ headers: {
54
+ 'Content-Type': 'application/json',
55
+ },
56
+ body: JSON.stringify({
57
+ model,
58
+ prompt,
59
+ temperature,
60
+ maxTokens
61
+ })
62
+ });
63
+
64
+ if (!response.ok) {
65
+ throw new Error(`LLM API error: ${response.status} ${response.statusText}`);
66
+ }
67
+
68
+ const data = await response.json();
69
+ const result = data.response || '';
70
+
71
+ if (session.debug) {
72
+ console.error(`[LLM] Response length: ${result.length}`);
73
+ }
74
+
75
+ // Store result if name provided
76
+ if (name) {
77
+ setVariable(session, name, result, false);
78
+ }
79
+
80
+ // Emit result
81
+ emit(session, result);
82
+
83
+ } catch (error) {
84
+ const errorMsg = error instanceof Error ? error.message : String(error);
85
+ console.error('[LLM] Error:', errorMsg);
86
+ throw new Error(`LLM call failed: ${errorMsg}`);
87
+ }
88
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * <loop> tag - iteration
3
+ * Maps to mask_tag_loop in MASK
4
+ */
5
+
6
+ import type { DiracSession, DiracElement } from '../types/index.js';
7
+ import { setVariable, substituteVariables, getVariable } from '../runtime/session.js';
8
+ import { integrateChildren } from '../runtime/interpreter.js';
9
+
10
+ export async function executeLoop(session: DiracSession, element: DiracElement): Promise<void> {
11
+ const countAttr = element.attributes.count;
12
+ const varName = element.attributes.var || 'i';
13
+
14
+ if (!countAttr) {
15
+ throw new Error('<loop> requires count attribute');
16
+ }
17
+
18
+ const count = parseInt(substituteVariables(session, countAttr), 10);
19
+
20
+ if (isNaN(count) || count < 0) {
21
+ throw new Error(`Invalid loop count: ${countAttr}`);
22
+ }
23
+
24
+ const wasBreak = session.isBreak;
25
+ session.isBreak = false;
26
+
27
+ for (let i = 0; i < count; i++) {
28
+ setVariable(session, varName, i, false);
29
+
30
+ await integrateChildren(session, element);
31
+
32
+ if (session.isBreak) {
33
+ session.isBreak = false;
34
+ break;
35
+ }
36
+
37
+ if (session.isReturn) {
38
+ break;
39
+ }
40
+ }
41
+
42
+ session.isBreak = wasBreak;
43
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * <output> tag - emit content
3
+ * Maps to mask_tag_output in MASK
4
+ */
5
+
6
+ import type { DiracSession, DiracElement } from '../types/index.js';
7
+ import { emit, substituteVariables } from '../runtime/session.js';
8
+ import { integrateChildren } from '../runtime/interpreter.js';
9
+
10
+ export async function executeOutput(session: DiracSession, element: DiracElement): Promise<void> {
11
+ // If has children, process them (handles mixed content)
12
+ if (element.children && element.children.length > 0) {
13
+ await integrateChildren(session, element);
14
+ return;
15
+ }
16
+
17
+ // If only text content, use it (with variable substitution)
18
+ if (element.text) {
19
+ const content = substituteVariables(session, element.text);
20
+ emit(session, content);
21
+ return;
22
+ }
23
+ }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * <parameters> tag - Access parameters passed to subroutine
3
+ * Maps to MASK parameter selection syntax
4
+ */
5
+
6
+ import type { DiracSession, DiracElement } from '../types/index.js';
7
+ import { getCurrentParameters, emit, setVariable } from '../runtime/session.js';
8
+ import { integrate } from '../runtime/interpreter.js';
9
+
10
+ export async function executeParameters(session: DiracSession, element: DiracElement): Promise<void> {
11
+ const select = element.attributes.select;
12
+
13
+ if (!select) {
14
+ throw new Error('<parameters> requires select attribute');
15
+ }
16
+
17
+ // Get parameters from current call context
18
+ const params = getCurrentParameters(session);
19
+
20
+ if (!params || params.length === 0) {
21
+ if (session.debug) {
22
+ console.error(`[PARAMETERS] No parameters available`);
23
+ }
24
+ return;
25
+ }
26
+
27
+ // The caller element is params[0] (the calling tag itself)
28
+ const caller = params[0];
29
+
30
+ if (select === '*') {
31
+ // Select all child elements - execute them
32
+ if (session.debug) {
33
+ console.error(`[PARAMETERS] Selecting all children (${caller.children.length} elements)`);
34
+ }
35
+
36
+ for (const child of caller.children) {
37
+ await integrate(session, child);
38
+ }
39
+
40
+ } else if (select.startsWith('@')) {
41
+ // Select attribute(s)
42
+ const attrName = select.slice(1); // Remove '@'
43
+
44
+ if (attrName === '*') {
45
+ // Select all attributes
46
+ if (session.debug) {
47
+ console.error(`[PARAMETERS] Selecting all attributes`);
48
+ }
49
+
50
+ const attrs = Object.entries(caller.attributes)
51
+ .map(([key, val]) => `${key}="${val}"`)
52
+ .join(' ');
53
+ emit(session, attrs);
54
+
55
+ } else {
56
+ // Select specific attribute - automatically create variable with that name
57
+ const value = caller.attributes[attrName];
58
+
59
+ if (session.debug) {
60
+ console.error(`[PARAMETERS] Setting variable '${attrName}' = '${value}'`);
61
+ }
62
+
63
+ if (value !== undefined) {
64
+ // Automatically create variable (like defvar)
65
+ setVariable(session, attrName, value, false);
66
+ }
67
+
68
+ // Execute children if any (for additional processing)
69
+ for (const child of element.children) {
70
+ await integrate(session, child);
71
+ }
72
+ }
73
+
74
+ } else {
75
+ throw new Error(`<parameters> invalid select: ${select}`);
76
+ }
77
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * <subroutine> tag - define reusable code block
3
+ * Maps to mask_tag_subroutine in MASK
4
+ */
5
+
6
+ import type { DiracSession, DiracElement, ParameterMetadata } from '../types/index.js';
7
+ import { registerSubroutine } from '../runtime/session.js';
8
+
9
+ export function executeSubroutine(session: DiracSession, element: DiracElement): void {
10
+ const name = element.attributes.name;
11
+
12
+ if (!name) {
13
+ throw new Error('<subroutine> requires name attribute');
14
+ }
15
+
16
+ // Extract metadata from attributes (no structural changes!)
17
+ const description = element.attributes.description;
18
+ const parameters: ParameterMetadata[] = [];
19
+
20
+ // Parse param- prefixed attributes for metadata
21
+ // e.g., param-color="string:required:Color name:red|blue|green"
22
+ for (const [attrName, attrValue] of Object.entries(element.attributes)) {
23
+ if (attrName.startsWith('param-')) {
24
+ const paramName = attrName.substring(6); // Remove "param-" prefix
25
+
26
+ // Parse format: "type:required:description:enum1|enum2|..."
27
+ const parts = attrValue.split(':');
28
+ const paramMeta: ParameterMetadata = {
29
+ name: paramName,
30
+ type: parts[0] || 'string',
31
+ required: parts[1] === 'required',
32
+ description: parts[2] || undefined,
33
+ };
34
+
35
+ // Parse enum if present (after 3rd colon)
36
+ if (parts[3]) {
37
+ paramMeta.enum = parts[3].split('|');
38
+ }
39
+
40
+ parameters.push(paramMeta);
41
+ }
42
+ }
43
+
44
+ // Store subroutine exactly as before (preserves nesting and extends)
45
+ const subroutine: DiracElement = {
46
+ tag: 'subroutine',
47
+ attributes: { ...element.attributes },
48
+ children: element.children,
49
+ };
50
+
51
+ registerSubroutine(session, name, subroutine, description, parameters.length > 0 ? parameters : undefined);
52
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * <variable> tag - retrieve variable value
3
+ * Outputs the stored variable content (text or tags)
4
+ */
5
+
6
+ import type { DiracSession, DiracElement } from '../types/index.js';
7
+ import { getVariable, emit } from '../runtime/session.js';
8
+
9
+ export function executeVariable(session: DiracSession, element: DiracElement): void {
10
+ const name = element.attributes.name;
11
+
12
+ if (!name) {
13
+ throw new Error('<variable> requires name attribute');
14
+ }
15
+
16
+ const value = getVariable(session, name);
17
+
18
+ if (value === undefined) {
19
+ if (session.debug) {
20
+ console.error(`[Warning] Variable '${name}' is undefined`);
21
+ }
22
+ return;
23
+ }
24
+
25
+ // Output the variable value
26
+ emit(session, String(value));
27
+ }
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Core types for Dirac interpreter
3
+ * Directly based on MASK C implementation
4
+ */
5
+
6
+ export interface DiracElement {
7
+ tag: string;
8
+ attributes: Record<string, string>;
9
+ children: DiracElement[];
10
+ text?: string;
11
+ }
12
+
13
+ /**
14
+ * Variable info - maps to VarInfo in MASK
15
+ */
16
+ export interface Variable {
17
+ name: string;
18
+ value: any;
19
+ visible: boolean;
20
+ boundary: number; // scope boundary marker
21
+ passby: 'value' | 'ref';
22
+ refName?: string; // for pass-by-reference
23
+ }
24
+
25
+ /**
26
+ * Subroutine info - maps to Subroutine in MASK
27
+ */
28
+ export interface Subroutine {
29
+ name: string;
30
+ element: DiracElement;
31
+ boundary: number; // scope boundary marker
32
+ extends?: string; // parent subroutine
33
+ description?: string; // For LLM reflection
34
+ parameters?: ParameterMetadata[]; // For LLM reflection
35
+ }
36
+
37
+ /**
38
+ * Parameter metadata for reflection API
39
+ */
40
+ export interface ParameterMetadata {
41
+ name: string;
42
+ type: string;
43
+ required: boolean;
44
+ description?: string;
45
+ enum?: string[];
46
+ }
47
+
48
+ /**
49
+ * Execution context - maps to MaskSession in MASK
50
+ */
51
+ export interface DiracSession {
52
+ // Variable stack (all variables are on stack)
53
+ variables: Variable[];
54
+
55
+ // Subroutine registry
56
+ subroutines: Subroutine[];
57
+
58
+ // Scope boundaries (for cleanup)
59
+ varBoundary: number;
60
+ subBoundary: number;
61
+
62
+ // Parameter stack (for subroutine calls)
63
+ parameterStack: DiracElement[][];
64
+
65
+ // Output buffer
66
+ output: string[];
67
+
68
+ // LLM client
69
+ llmClient?: any;
70
+
71
+ // Execution limits
72
+ limits: {
73
+ maxLLMCalls: number;
74
+ currentLLMCalls: number;
75
+ maxDepth: number;
76
+ currentDepth: number;
77
+ };
78
+
79
+ // Control flow
80
+ isReturn: boolean;
81
+ isBreak: boolean;
82
+
83
+ // Debugging
84
+ debug: boolean;
85
+
86
+ // Import tracking
87
+ currentFile?: string;
88
+ importedFiles?: Set<string>;
89
+
90
+ // Configuration reference
91
+ config: DiracConfig;
92
+ }
93
+
94
+ export interface DiracConfig {
95
+ apiKey?: string;
96
+ model?: string;
97
+ debug?: boolean;
98
+ maxLLMCalls?: number;
99
+ maxDepth?: number;
100
+ filePath?: string; // Current file path for imports
101
+ customContext?: Record<string, any>; // Custom context for browser integration
102
+ llmBackendUrl?: string; // Backend URL for LLM calls (browser edition)
103
+ }
@@ -0,0 +1,118 @@
1
+ /**
2
+ * LLM Adapter - Auto-generate prompts and JSON→XML converters
3
+ * from Dirac subroutine definitions
4
+ */
5
+
6
+ import type { DiracSession } from '../types/index.js';
7
+ import { getAvailableSubroutines } from '../runtime/session.js';
8
+
9
+ export interface LLMPromptGenerator {
10
+ generatePrompt(userInput: string): string;
11
+ intentToXML(intent: any): string | null;
12
+ getAvailableActions(): string[];
13
+ }
14
+
15
+ /**
16
+ * Create LLM adapter from session's registered subroutines
17
+ */
18
+ export function createLLMAdapter(session: DiracSession): LLMPromptGenerator {
19
+ const subroutines = getAvailableSubroutines(session);
20
+
21
+ // Build JSON schema from subroutines
22
+ const actions = subroutines.map(s => `"${s.name}"`).join('|');
23
+
24
+ // Build examples
25
+ const examples = subroutines.slice(0, 3).map(sub => {
26
+ if (!sub.parameters || sub.parameters.length === 0) {
27
+ return `"${sub.name}" → {"action":"${sub.name}","params":{}}`;
28
+ }
29
+
30
+ const firstParam = sub.parameters[0];
31
+ const exampleValue = firstParam.enum?.[0] || 'value';
32
+ return `"call ${sub.name}" → {"action":"${sub.name}","params":{"${firstParam.name}":"${exampleValue}"}}`;
33
+ }).join('\n');
34
+
35
+ return {
36
+ generatePrompt(userInput: string): string {
37
+ return `You are a command parser. Convert user input to JSON.
38
+ Return ONLY valid JSON, no other text.
39
+
40
+ Format: {"action": ${actions}, "params": {}}
41
+
42
+ Examples:
43
+ ${examples}
44
+
45
+ User: ${userInput}
46
+ JSON:`;
47
+ },
48
+
49
+ intentToXML(intent: any): string | null {
50
+ if (!intent || !intent.action) return null;
51
+
52
+ const sub = subroutines.find(s => s.name === intent.action);
53
+ if (!sub) return null;
54
+
55
+ const attrs: string[] = [`name="${sub.name}"`];
56
+
57
+ // Map params to XML attributes
58
+ if (sub.parameters) {
59
+ for (const param of sub.parameters) {
60
+ const value = intent.params?.[param.name];
61
+
62
+ if (value != null) {
63
+ // Validate enum if present
64
+ if (param.enum && !param.enum.includes(value)) {
65
+ return null;
66
+ }
67
+ attrs.push(`${param.name}="${value}"`);
68
+ } else if (param.required) {
69
+ return null; // Missing required parameter
70
+ }
71
+ }
72
+ }
73
+
74
+ return `<call ${attrs.join(' ')}/>`;
75
+ },
76
+
77
+ getAvailableActions(): string[] {
78
+ return subroutines.map(s => s.name);
79
+ }
80
+ };
81
+ }
82
+
83
+ /**
84
+ * Higher-level helper: execute user command via LLM
85
+ */
86
+ export async function executeUserCommand(
87
+ session: DiracSession,
88
+ userInput: string,
89
+ llmExecuteFn: (prompt: string) => Promise<string>
90
+ ): Promise<{ success: boolean; xml?: string; error?: string }> {
91
+ try {
92
+ const adapter = createLLMAdapter(session);
93
+ const prompt = adapter.generatePrompt(userInput);
94
+
95
+ // Call LLM
96
+ const llmResponse = await llmExecuteFn(prompt);
97
+
98
+ // Parse JSON
99
+ let jsonStr = llmResponse.trim();
100
+ jsonStr = jsonStr.replace(/```json\s*/g, '').replace(/```\s*/g, '');
101
+
102
+ const intent = JSON.parse(jsonStr);
103
+
104
+ // Convert to XML
105
+ const xml = adapter.intentToXML(intent);
106
+
107
+ if (!xml) {
108
+ return { success: false, error: 'Could not convert intent to valid command' };
109
+ }
110
+
111
+ return { success: true, xml };
112
+ } catch (error) {
113
+ return {
114
+ success: false,
115
+ error: error instanceof Error ? error.message : String(error)
116
+ };
117
+ }
118
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "ES2020",
5
+ "lib": ["ES2020", "DOM"],
6
+ "declaration": true,
7
+ "outDir": "./dist",
8
+ "rootDir": "./src",
9
+ "strict": true,
10
+ "esModuleInterop": true,
11
+ "skipLibCheck": true,
12
+ "forceConsistentCasingInFileNames": true,
13
+ "moduleResolution": "node",
14
+ "resolveJsonModule": true
15
+ },
16
+ "include": ["src/**/*"],
17
+ "exclude": ["node_modules", "dist"]
18
+ }