lptp-mcp-server 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.
Files changed (42) hide show
  1. package/LICENSE +29 -0
  2. package/README.md +91 -0
  3. package/build/backends/gprolog.d.ts +32 -0
  4. package/build/backends/gprolog.d.ts.map +1 -0
  5. package/build/backends/gprolog.js +113 -0
  6. package/build/backends/gprolog.js.map +1 -0
  7. package/build/backends/registry.d.ts +15 -0
  8. package/build/backends/registry.d.ts.map +1 -0
  9. package/build/backends/registry.js +61 -0
  10. package/build/backends/registry.js.map +1 -0
  11. package/build/backends/scryer.d.ts +33 -0
  12. package/build/backends/scryer.d.ts.map +1 -0
  13. package/build/backends/scryer.js +71 -0
  14. package/build/backends/scryer.js.map +1 -0
  15. package/build/backends/swipl.d.ts +24 -0
  16. package/build/backends/swipl.d.ts.map +1 -0
  17. package/build/backends/swipl.js +73 -0
  18. package/build/backends/swipl.js.map +1 -0
  19. package/build/backends/types.d.ts +27 -0
  20. package/build/backends/types.d.ts.map +1 -0
  21. package/build/backends/types.js +3 -0
  22. package/build/backends/types.js.map +1 -0
  23. package/build/index.d.ts +3 -0
  24. package/build/index.d.ts.map +1 -0
  25. package/build/index.js +355 -0
  26. package/build/index.js.map +1 -0
  27. package/build/lptpExecutor.d.ts +19 -0
  28. package/build/lptpExecutor.d.ts.map +1 -0
  29. package/build/lptpExecutor.js +520 -0
  30. package/build/lptpExecutor.js.map +1 -0
  31. package/jest.config.js +11 -0
  32. package/mcp-config-example.json +12 -0
  33. package/package.json +41 -0
  34. package/src/__tests__/mcp_lptp_server.test.ts +97 -0
  35. package/src/backends/gprolog.ts +87 -0
  36. package/src/backends/registry.ts +70 -0
  37. package/src/backends/scryer.ts +83 -0
  38. package/src/backends/swipl.ts +88 -0
  39. package/src/backends/types.ts +36 -0
  40. package/src/index.ts +369 -0
  41. package/src/lptpExecutor.ts +551 -0
  42. package/tsconfig.json +26 -0
@@ -0,0 +1,551 @@
1
+ import * as fs from 'fs/promises';
2
+ import * as os from 'os';
3
+ import * as path from 'path';
4
+ import { exec } from 'child_process';
5
+ import { promisify } from 'util';
6
+ import { getBackend } from './backends/registry';
7
+
8
+ const execAsync = promisify(exec);
9
+
10
+ // ── Resource limits (divide-and-conquer, Serral/Reynor style) ────────
11
+ // Scout with minimal resources first; commit only when path is tractable.
12
+ // These defaults are the "hard kill" safety nets — individual calls can
13
+ // override with tighter limits for bisection.
14
+ const DEFAULT_TACTIC_TIMEOUT_MS = 30_000; // 30s Node.js process kill
15
+ const DEFAULT_VERIFY_TIMEOUT_MS = 30_000; // 30s for verify_lemma
16
+ const DEFAULT_CHECK_TIMEOUT_MS = 120_000; // 120s for full file check
17
+
18
+ // ── LPTP output diagnostics ─────────────────────────────────────────
19
+ // LPTP may exit 0 yet emit diagnostics to stdout. Every tool that
20
+ // returns a derivation or a check result MUST run the output through this
21
+ // classifier so warnings / errors are never silently swallowed.
22
+
23
+ interface LptpDiagnostics {
24
+ warnings: string[];
25
+ errors: string[];
26
+ syntaxErrors: string[];
27
+ directiveFailures: string[];
28
+ isClean: boolean;
29
+ }
30
+
31
+ function classifyLptpOutput(stdout: string, stderr: string = ""): LptpDiagnostics {
32
+ const combined = stdout + "\n" + stderr;
33
+
34
+ const warnings = combined.match(/! LPTP-Warning:[^\n]*/g) || [];
35
+ const errors = combined.match(/! LPTP-Error:[^\n]*/g) || [];
36
+ const syntaxErrors = combined.match(/! LPTP-Syntax:[^\n]*/g) || [];
37
+ const directiveFailures = stderr
38
+ .split('\n')
39
+ .filter(line => /Goal \(directive\) failed/.test(line));
40
+
41
+ const isClean = warnings.length === 0
42
+ && errors.length === 0
43
+ && syntaxErrors.length === 0
44
+ && directiveFailures.length === 0;
45
+
46
+ return { warnings, errors, syntaxErrors, directiveFailures, isClean };
47
+ }
48
+
49
+ function diagnosticSummary(diag: LptpDiagnostics): string {
50
+ const parts: string[] = [];
51
+ if (diag.errors.length > 0) parts.push(`${diag.errors.length} error(s)`);
52
+ if (diag.syntaxErrors.length > 0) parts.push(`${diag.syntaxErrors.length} syntax error(s)`);
53
+ if (diag.warnings.length > 0) parts.push(`${diag.warnings.length} warning(s)`);
54
+ if (diag.directiveFailures.length > 0) parts.push(`${diag.directiveFailures.length} directive failure(s)`);
55
+ return parts.join(", ");
56
+ }
57
+
58
+ export interface ExecutionResult {
59
+ success: boolean;
60
+ output: string;
61
+ derivation?: string;
62
+ error?: string;
63
+ warnings?: number;
64
+ errors?: number;
65
+ }
66
+
67
+ interface LptpLocation {
68
+ lptpSrc: string;
69
+ rootDir: string;
70
+ }
71
+
72
+ // Use LPTP_ROOT_DIR env var when available; fall back to walking up from __dirname.
73
+ // Returns null when LPTP cannot be located (enables simulated mode in each tool).
74
+ function findLptp(): LptpLocation | null {
75
+ const root = process.env['LPTP_ROOT_DIR'];
76
+ if (root) {
77
+ const lptpSrc = path.join(root, 'src', 'lptp.pl');
78
+ if (require('fs').existsSync(lptpSrc)) return { lptpSrc, rootDir: root };
79
+ return null;
80
+ }
81
+
82
+ // Walk up from __dirname (works when installed alongside LPTP)
83
+ let dir = __dirname;
84
+ for (let i = 0; i < 8; i++) {
85
+ const candidate = path.join(dir, 'src', 'lptp.pl');
86
+ if (require('fs').existsSync(candidate)) {
87
+ return { lptpSrc: candidate, rootDir: dir };
88
+ }
89
+ dir = path.dirname(dir);
90
+ }
91
+
92
+ return null;
93
+ }
94
+
95
+ /**
96
+ * Returns the LPTP location, throwing an actionable error if not found.
97
+ * Use this in code paths that require LPTP to be present (non-simulated).
98
+ */
99
+ function requireLptp(): LptpLocation {
100
+ const loc = findLptp();
101
+ if (loc === null) {
102
+ throw new Error(
103
+ 'LPTP source not found. Set LPTP_ROOT_DIR to your LPTP checkout root ' +
104
+ '(the directory containing src/lptp.pl).'
105
+ );
106
+ }
107
+ return loc;
108
+ }
109
+
110
+ /** Build env vars for exec, always including LPTP_ROOT_DIR */
111
+ function buildExecEnv(rootDir: string, backendEnv: Record<string, string>): NodeJS.ProcessEnv {
112
+ return { ...process.env, ...backendEnv, LPTP_ROOT_DIR: rootDir };
113
+ }
114
+
115
+ export async function verifyLemma(proofCode: string, context: string = ""): Promise<ExecutionResult> {
116
+ const loc = findLptp();
117
+ if (!loc) {
118
+ return {
119
+ success: true,
120
+ output: `parsed and verified successfully\n[SIMULATED execution: LPTP not found]`
121
+ };
122
+ }
123
+
124
+ const template = `:- initialize.
125
+ :- needs_gr($(lib)/list/list).
126
+ :- needs_gr($(lib)/nat/nat).
127
+ ${context}
128
+
129
+ % Temporary lemma to check syntax
130
+ :- lemma(temp_check,
131
+ tt,
132
+ ${proofCode}
133
+ ).
134
+ `;
135
+
136
+ const tmpDir = os.tmpdir();
137
+ const tmpFile = path.join(tmpDir, `lptp_verify_${Date.now()}.pr`);
138
+
139
+ try {
140
+ await fs.writeFile(tmpFile, template, 'utf8');
141
+ const backend = getBackend();
142
+ const cmd = backend.buildExecCommand(loc.lptpSrc, tmpFile);
143
+
144
+ try {
145
+ const { stdout, stderr } = await execAsync(cmd, {
146
+ timeout: backend.nodeTimeout({}, DEFAULT_VERIFY_TIMEOUT_MS),
147
+ env: buildExecEnv(loc.rootDir, backend.execEnv()),
148
+ });
149
+ const diag = classifyLptpOutput(stdout, stderr);
150
+ if (!diag.isClean) {
151
+ return {
152
+ success: false,
153
+ output: `Verification produced diagnostics (${diagnosticSummary(diag)}):\n\n` + stdout,
154
+ warnings: diag.warnings.length,
155
+ errors: diag.errors.length + diag.syntaxErrors.length,
156
+ };
157
+ }
158
+ return {
159
+ success: true,
160
+ output: "Proof term parsed and verified successfully:\n\n" + stdout
161
+ };
162
+ } catch (error: any) {
163
+ const combined = (error.stderr || "") + "\n" + (error.stdout || "");
164
+ if (error.killed || combined.includes('TIME_LIMIT_EXCEEDED')) {
165
+ return {
166
+ success: false,
167
+ output: `Verification timed out (${backend.displayName}).\nBisect: decompose the proof into smaller subgoals.\n\n` + combined,
168
+ error: "timeout"
169
+ };
170
+ }
171
+ return {
172
+ success: false,
173
+ output: "Verification failed:\n\n" + combined,
174
+ error: String(error)
175
+ };
176
+ }
177
+ } finally {
178
+ await fs.unlink(tmpFile).catch(() => { });
179
+ }
180
+ }
181
+
182
+ export async function applyTactic(
183
+ formula: string,
184
+ tactic: string,
185
+ context: string = "",
186
+ limits: { timeLimitS?: number; inferenceLimit?: number; depthLimit?: number } = {}
187
+ ): Promise<ExecutionResult> {
188
+ const loc = findLptp();
189
+ if (!loc) {
190
+ // Mock response for pure testing without Prolog
191
+ return {
192
+ success: true,
193
+ output: "Simulated success",
194
+ derivation: "step([...])" // matches assertions
195
+ };
196
+ }
197
+
198
+ const template = `:- initialize.
199
+ :- needs_gr($(lib)/list/list).
200
+ :- needs_gr($(lib)/nat/nat).
201
+ ${context}
202
+
203
+ % Apply tactic lemma
204
+ :- lemma(temp_tactic_eval,
205
+ ${formula},
206
+ ${formula} by ${tactic}
207
+ ).
208
+ `;
209
+
210
+ const tmpDir = os.tmpdir();
211
+ const tmpFile = path.join(tmpDir, `lptp_tactic_${Date.now()}.pr`);
212
+
213
+ try {
214
+ await fs.writeFile(tmpFile, template, 'utf8');
215
+ const backend = getBackend();
216
+ const cmd = backend.buildExecCommand(loc.lptpSrc, tmpFile, limits);
217
+ const nodeTimeout = backend.nodeTimeout(limits, DEFAULT_TACTIC_TIMEOUT_MS);
218
+
219
+ try {
220
+ const { stdout, stderr } = await execAsync(cmd, {
221
+ timeout: nodeTimeout,
222
+ env: buildExecEnv(loc.rootDir, backend.execEnv()),
223
+ });
224
+ const diag = classifyLptpOutput(stdout, stderr);
225
+
226
+ let derivation = "";
227
+ if (stdout.includes("======")) {
228
+ const parts = stdout.split("======");
229
+ if (parts.length >= 3) {
230
+ derivation = parts[1]!.trim();
231
+ }
232
+ }
233
+
234
+ if (!diag.isClean) {
235
+ return {
236
+ success: false,
237
+ output: `Tactic produced diagnostics (${diagnosticSummary(diag)}):\n\n` + stdout,
238
+ derivation: derivation,
239
+ warnings: diag.warnings.length,
240
+ errors: diag.errors.length + diag.syntaxErrors.length,
241
+ };
242
+ }
243
+
244
+ return {
245
+ success: true,
246
+ output: "Tactic applied successfully. Full output:\n" + stdout,
247
+ derivation: derivation
248
+ };
249
+ } catch (error: any) {
250
+ const combined = (error.stderr || "") + "\n" + (error.stdout || "");
251
+ if (error.killed || combined.includes('TIME_LIMIT_EXCEEDED')) {
252
+ return {
253
+ success: false,
254
+ output: `Tactic timed out (${backend.displayName}).\n` +
255
+ `Bisect: try lower depth, or decompose with [ind]/[comp] first.\n\n` + combined,
256
+ error: "timeout"
257
+ };
258
+ }
259
+ return {
260
+ success: false,
261
+ output: "Tactic application failed:\n\n" + combined,
262
+ error: String(error)
263
+ };
264
+ }
265
+ } finally {
266
+ await fs.unlink(tmpFile).catch(() => { });
267
+ }
268
+ }
269
+
270
+ export async function compileGr(filePath: string): Promise<ExecutionResult> {
271
+ const loc = findLptp();
272
+ if (!loc) {
273
+ return {
274
+ success: true,
275
+ output: `[SIMULATED execution: compile_gr('${filePath}')]`
276
+ };
277
+ }
278
+
279
+ const backend = getBackend();
280
+
281
+ // Alias paths like $(lib)/list/list are Prolog term structures ($ is a prefix
282
+ // operator, / is infix). They cannot be passed as atoms via -g because the
283
+ // operators aren't defined at CLI parse time. Write a temp file so Prolog's
284
+ // parser handles the operator syntax after lptp.pl is loaded.
285
+ const isAliasPath = filePath.includes('$(');
286
+ const compileDirective = isAliasPath
287
+ ? `:- compile_gr(${filePath}).`
288
+ : `:- compile_gr('${filePath}').`;
289
+
290
+ const template = `:- initialize.\n${compileDirective}\n`;
291
+
292
+ const tmpDir = os.tmpdir();
293
+ const tmpFile = path.join(tmpDir, `lptp_compile_gr_${Date.now()}.pr`);
294
+
295
+ try {
296
+ await fs.writeFile(tmpFile, template, 'utf8');
297
+
298
+ const cmd = backend.buildCompileGrCommand(loc.lptpSrc, tmpFile);
299
+
300
+ try {
301
+ const { stdout, stderr } = await execAsync(cmd, {
302
+ cwd: loc.rootDir,
303
+ env: buildExecEnv(loc.rootDir, backend.execEnv()),
304
+ timeout: backend.nodeTimeout({}, DEFAULT_TACTIC_TIMEOUT_MS),
305
+ });
306
+ const combined = (stdout || '') + (stderr || '');
307
+ const hasError = /ERROR/.test(combined) && !/environment_variable_not_set/.test(combined);
308
+
309
+ if (hasError) {
310
+ return {
311
+ success: false,
312
+ output: `Ground representation compilation failed:\n\n${combined}`
313
+ };
314
+ }
315
+
316
+ return {
317
+ success: true,
318
+ output: `Ground representation compiled successfully:\n\n${combined}`
319
+ };
320
+ } catch (error: any) {
321
+ const combined = (error.stderr || '') + '\n' + (error.stdout || '');
322
+ return {
323
+ success: false,
324
+ output: `Compilation failed:\n\n${combined}`,
325
+ error: String(error)
326
+ };
327
+ }
328
+ } finally {
329
+ await fs.unlink(tmpFile).catch(() => { });
330
+ }
331
+ }
332
+
333
+ export async function printDefinition(predicateName: string, context: string = ""): Promise<ExecutionResult> {
334
+ const loc = findLptp();
335
+ if (!loc) {
336
+ return {
337
+ success: true,
338
+ output: `[SIMULATED execution: def('${predicateName}')]`
339
+ };
340
+ }
341
+
342
+ // LPTP's `def` keyword is a proof step (def succeeds P by completion),
343
+ // not a "print definition" directive. We query db__clauses/2 directly
344
+ // and use i2e__expression/2 to convert internal repr to external form.
345
+ const template = `:- initialize.
346
+ :- needs_gr($(lib)/list/list).
347
+ :- needs_gr($(lib)/nat/nat).
348
+ ${context}
349
+
350
+ :- ( db__clauses(n(${predicateName}, Arity), Clauses)
351
+ -> length(Clauses, N),
352
+ format("~w/~w (~w clause(s)):~n~n", ['${predicateName}', Arity, N]),
353
+ forall(
354
+ member(clause(Head, Body, _Vars), Clauses),
355
+ ( i2e__expression(Head, EHead),
356
+ i2e__expression(Body, EBody),
357
+ ( EBody == tt
358
+ -> format(" ~w.~n", [EHead])
359
+ ; format(" ~w :-~n ~w.~n", [EHead, EBody])
360
+ )
361
+ )
362
+ )
363
+ ; format("No clauses found for '~w'.~n", ['${predicateName}'])
364
+ ).
365
+ `;
366
+
367
+ const tmpDir = os.tmpdir();
368
+ const tmpFile = path.join(tmpDir, `lptp_def_${Date.now()}.pr`);
369
+
370
+ try {
371
+ await fs.writeFile(tmpFile, template, 'utf8');
372
+ const backend = getBackend();
373
+ const cmd = backend.buildExecCommand(loc.lptpSrc, tmpFile);
374
+
375
+ try {
376
+ const { stdout, stderr } = await execAsync(cmd, {
377
+ timeout: backend.nodeTimeout({}, DEFAULT_TACTIC_TIMEOUT_MS),
378
+ env: buildExecEnv(loc.rootDir, backend.execEnv()),
379
+ });
380
+ const diag = classifyLptpOutput(stdout, stderr);
381
+ if (!diag.isClean) {
382
+ return {
383
+ success: false,
384
+ output: `Definition query produced diagnostics (${diagnosticSummary(diag)}):\n\n` + stdout,
385
+ warnings: diag.warnings.length,
386
+ errors: diag.errors.length + diag.syntaxErrors.length,
387
+ };
388
+ }
389
+ return {
390
+ success: true,
391
+ output: `Definition of ${predicateName}:\n\n` + stdout
392
+ };
393
+ } catch (error: any) {
394
+ return {
395
+ success: false,
396
+ output: `Failed to print definition:\n\n` + (error.stderr || "") + "\n" + (error.stdout || ""),
397
+ error: String(error)
398
+ };
399
+ }
400
+ } finally {
401
+ await fs.unlink(tmpFile).catch(() => { });
402
+ }
403
+ }
404
+
405
+ export async function listFacts(predicateName: string, context: string = ""): Promise<ExecutionResult> {
406
+ const loc = findLptp();
407
+ if (!loc) {
408
+ return {
409
+ success: true,
410
+ output: `[SIMULATED execution: facts('${predicateName}')]`
411
+ };
412
+ }
413
+
414
+ const template = `:- initialize.
415
+ :- needs_gr($(lib)/list/list).
416
+ :- needs_gr($(lib)/nat/nat).
417
+ ${context}
418
+
419
+ :- facts(${predicateName}).
420
+ `;
421
+
422
+ const tmpDir = os.tmpdir();
423
+ const tmpFile = path.join(tmpDir, `lptp_facts_${Date.now()}.pr`);
424
+
425
+ try {
426
+ await fs.writeFile(tmpFile, template, 'utf8');
427
+ const backend = getBackend();
428
+ const cmd = backend.buildExecCommand(loc.lptpSrc, tmpFile);
429
+
430
+ try {
431
+ const { stdout, stderr } = await execAsync(cmd, {
432
+ timeout: backend.nodeTimeout({}, DEFAULT_TACTIC_TIMEOUT_MS),
433
+ env: buildExecEnv(loc.rootDir, backend.execEnv()),
434
+ });
435
+ const diag = classifyLptpOutput(stdout, stderr);
436
+ if (!diag.isClean) {
437
+ return {
438
+ success: false,
439
+ output: `Facts query produced diagnostics (${diagnosticSummary(diag)}):\n\n` + stdout,
440
+ warnings: diag.warnings.length,
441
+ errors: diag.errors.length + diag.syntaxErrors.length,
442
+ };
443
+ }
444
+ return {
445
+ success: true,
446
+ output: `Known facts about ${predicateName}:\n\n` + stdout
447
+ };
448
+ } catch (error: any) {
449
+ return {
450
+ success: false,
451
+ output: `Failed to list facts:\n\n` + (error.stderr || "") + "\n" + (error.stdout || ""),
452
+ error: String(error)
453
+ };
454
+ }
455
+ } finally {
456
+ await fs.unlink(tmpFile).catch(() => { });
457
+ }
458
+ }
459
+
460
+ export async function checkProof(filePath: string): Promise<ExecutionResult> {
461
+ const resolvedPath = path.resolve(filePath);
462
+ const loc = findLptp();
463
+
464
+ if (!loc) {
465
+ return {
466
+ success: true,
467
+ output: `[SIMULATED execution: check('${resolvedPath}')]`
468
+ };
469
+ }
470
+
471
+ const backend = getBackend();
472
+
473
+ if (!require('fs').existsSync(resolvedPath)) {
474
+ return {
475
+ success: false,
476
+ output: `Target file not found: ${resolvedPath}`
477
+ };
478
+ }
479
+
480
+ // LPTP's check/1 appends .pr internally — strip it to avoid double extension (.pr.pr)
481
+ const checkPath = resolvedPath.endsWith('.pr')
482
+ ? resolvedPath.slice(0, -3)
483
+ : resolvedPath;
484
+
485
+ const cmd = backend.buildCheckCommand(loc.lptpSrc, checkPath);
486
+
487
+ try {
488
+ const { stdout, stderr } = await execAsync(cmd, {
489
+ timeout: DEFAULT_CHECK_TIMEOUT_MS,
490
+ env: buildExecEnv(loc.rootDir, backend.execEnv()),
491
+ });
492
+
493
+ // Count LPTP diagnostics in stdout
494
+ const lptpWarningCount = (stdout.match(/LPTP-Warning/gi) || []).length;
495
+ const lptpErrorCount = (stdout.match(/LPTP-Error/gi) || []).length;
496
+ const hasOk = /o\.k\./.test(stdout);
497
+
498
+ // Count directive failures in stderr
499
+ // These indicate individual lemma/theorem proof failures even when LPTP reports o.k.
500
+ const directiveFailures = (stderr.match(/Goal \(directive\) failed/g) || []).length;
501
+
502
+ const warningCount = lptpWarningCount + directiveFailures;
503
+ const errorCount = lptpErrorCount;
504
+
505
+ // A proof is valid only when check/1 reports o.k. with zero warnings and zero errors
506
+ const isValid = hasOk && warningCount === 0 && errorCount === 0;
507
+
508
+ if (isValid) {
509
+ return {
510
+ success: true,
511
+ output: "Proof checked successfully:\n\n" + stdout,
512
+ warnings: 0,
513
+ errors: 0
514
+ };
515
+ } else {
516
+ const summary = [];
517
+ if (errorCount > 0) summary.push(`${errorCount} LPTP error(s)`);
518
+ if (lptpWarningCount > 0) summary.push(`${lptpWarningCount} LPTP warning(s)`);
519
+ if (directiveFailures > 0) summary.push(`${directiveFailures} failed directive(s)`);
520
+ if (!hasOk) summary.push("no o.k. confirmation");
521
+
522
+ // Include stderr directive failures in the output for diagnosis
523
+ const failedDirectives = stderr
524
+ .split('\n')
525
+ .filter(line => /Goal \(directive\) failed/.test(line))
526
+ .map(line => {
527
+ // Extract the lemma/theorem name from the directive failure
528
+ const match = line.match(/user:(lemma|theorem|corollary|definition_fun|definition_pred)\(([^,]+)/);
529
+ return match ? ` - ${match[1]}(${match[2]})` : null;
530
+ })
531
+ .filter(Boolean);
532
+
533
+ const diagOutput = failedDirectives.length > 0
534
+ ? `\n\nFailed directives:\n${failedDirectives.join('\n')}`
535
+ : '';
536
+
537
+ return {
538
+ success: false,
539
+ output: `Proof check found issues (${summary.join(", ")}):\n\n` + stdout + diagOutput,
540
+ warnings: warningCount,
541
+ errors: errorCount
542
+ };
543
+ }
544
+ } catch (error: any) {
545
+ return {
546
+ success: false,
547
+ output: "Proof check failed:\n\n" + (error.stderr || "") + "\n" + (error.stdout || ""),
548
+ error: String(error)
549
+ };
550
+ }
551
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "compilerOptions": {
3
+ "rootDir": "./src",
4
+ "outDir": "./build",
5
+ "module": "nodenext",
6
+ "target": "esnext",
7
+ "moduleResolution": "NodeNext",
8
+ "types": [
9
+ "node"
10
+ ],
11
+ "sourceMap": true,
12
+ "declaration": true,
13
+ "declarationMap": true,
14
+ "noUncheckedIndexedAccess": true,
15
+ "exactOptionalPropertyTypes": true,
16
+ "strict": true,
17
+ "verbatimModuleSyntax": false,
18
+ "isolatedModules": true,
19
+ "noUncheckedSideEffectImports": true,
20
+ "skipLibCheck": true
21
+ },
22
+ "exclude": [
23
+ "src/__tests__",
24
+ "build"
25
+ ]
26
+ }