kopscript 0.1.0 → 0.3.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/LLM.md +377 -0
- package/README.md +111 -22
- package/assets/logo.png +0 -0
- package/dist/checker.js +194 -20
- package/dist/cli.js +85 -16
- package/dist/codegen.js +9 -1
- package/dist/lexer.js +4 -0
- package/dist/modules.js +6 -3
- package/dist/parser.js +78 -18
- package/dist/tokens.js +3 -0
- package/dist/types.js +31 -16
- package/package.json +4 -2
package/dist/modules.js
CHANGED
|
@@ -29,7 +29,7 @@ export function loadModuleGraph(entryAbsPath) {
|
|
|
29
29
|
const diagnostics = new DiagnosticBag();
|
|
30
30
|
const tokens = new Lexer(source, diagnostics).tokenize();
|
|
31
31
|
const program = new Parser(tokens, diagnostics).parseProgram();
|
|
32
|
-
const record = { absPath, source, program, diagnostics, dependencies: [] };
|
|
32
|
+
const record = { absPath, source, program, diagnostics, dependencies: [], hoverEntries: [] };
|
|
33
33
|
modules.set(absPath, record);
|
|
34
34
|
stack.push(absPath);
|
|
35
35
|
for (const u of program.usings) {
|
|
@@ -66,6 +66,7 @@ export function compileGraph(entryAbsPath) {
|
|
|
66
66
|
return { success: false, entryMissing: true, modules, order, outputs: new Map() };
|
|
67
67
|
}
|
|
68
68
|
const exportsByModule = new Map();
|
|
69
|
+
const rawContentsByModule = new Map();
|
|
69
70
|
let hasErrors = false;
|
|
70
71
|
for (const absPath of order) {
|
|
71
72
|
const mod = modules.get(absPath);
|
|
@@ -104,11 +105,13 @@ export function compileGraph(entryAbsPath) {
|
|
|
104
105
|
for (const [name, info] of depExports.enums)
|
|
105
106
|
merged.enums.set(name, info);
|
|
106
107
|
}
|
|
107
|
-
const checker = new Checker(mod.program, mod.diagnostics, merged);
|
|
108
|
+
const checker = new Checker(mod.program, mod.diagnostics, merged, absPath);
|
|
108
109
|
checker.check();
|
|
110
|
+
mod.hoverEntries = checker.hoverEntries;
|
|
109
111
|
if (mod.diagnostics.hasErrors)
|
|
110
112
|
hasErrors = true;
|
|
111
113
|
exportsByModule.set(absPath, checker.getExports());
|
|
114
|
+
rawContentsByModule.set(absPath, checker.getRawContents());
|
|
112
115
|
}
|
|
113
116
|
if (hasErrors) {
|
|
114
117
|
return { success: false, entryMissing: false, modules, order, outputs: new Map() };
|
|
@@ -127,7 +130,7 @@ export function compileGraph(entryAbsPath) {
|
|
|
127
130
|
usingExports.set(u.path, [...importableTypeNames, ...depExports.functions.keys(), ...depExports.externValues.keys()]);
|
|
128
131
|
}
|
|
129
132
|
}
|
|
130
|
-
outputs.set(absPath, new CodeGenerator().generate(mod.program, usingExports));
|
|
133
|
+
outputs.set(absPath, new CodeGenerator().generate(mod.program, usingExports, rawContentsByModule.get(absPath) ?? new Map()));
|
|
131
134
|
}
|
|
132
135
|
return { success: true, entryMissing: false, modules, order, outputs };
|
|
133
136
|
}
|
package/dist/parser.js
CHANGED
|
@@ -50,6 +50,8 @@ export class Parser {
|
|
|
50
50
|
return this.parseEnumDecl(true);
|
|
51
51
|
if (this.check(TokenKind.Extern))
|
|
52
52
|
return this.parseExternDecl(true);
|
|
53
|
+
if (this.check(TokenKind.Raw))
|
|
54
|
+
return this.parseRawStringDecl(true);
|
|
53
55
|
if (this.check(TokenKind.LBrace))
|
|
54
56
|
return this.parseBlock();
|
|
55
57
|
if (this.check(TokenKind.If))
|
|
@@ -102,6 +104,8 @@ export class Parser {
|
|
|
102
104
|
return this.parseEnumDecl(isExported);
|
|
103
105
|
if (this.check(TokenKind.Extern))
|
|
104
106
|
return this.parseExternDecl(isExported);
|
|
107
|
+
if (this.check(TokenKind.Raw))
|
|
108
|
+
return this.parseRawStringDecl(isExported);
|
|
105
109
|
if (this.isDeclStart()) {
|
|
106
110
|
const decl = this.parseDeclaration(isExported);
|
|
107
111
|
if (decl.kind === "VarDecl") {
|
|
@@ -149,7 +153,8 @@ export class Parser {
|
|
|
149
153
|
this.advance();
|
|
150
154
|
}
|
|
151
155
|
const type = this.parseType();
|
|
152
|
-
const
|
|
156
|
+
const nameTok = this.consume(TokenKind.Identifier, "Expected name");
|
|
157
|
+
const name = nameTok.lexeme;
|
|
153
158
|
if (this.check(TokenKind.LParen)) {
|
|
154
159
|
const params = this.parseParamList();
|
|
155
160
|
const body = this.parseBlock();
|
|
@@ -161,7 +166,7 @@ export class Parser {
|
|
|
161
166
|
this.consume(TokenKind.Assign, "Expected '=' in variable declaration");
|
|
162
167
|
const init = this.parseExpression();
|
|
163
168
|
this.consume(TokenKind.Semicolon, "Expected ';' after variable declaration");
|
|
164
|
-
return { kind: "VarDecl", isConst: false, name, type, init, line: start.line, col: start.col };
|
|
169
|
+
return { kind: "VarDecl", isConst: false, name, nameLine: nameTok.line, nameCol: nameTok.col, type, init, line: start.line, col: start.col };
|
|
165
170
|
}
|
|
166
171
|
// Parses `Type name = init` without consuming a trailing terminator — used
|
|
167
172
|
// both for top-level/block statements (which add the `;`) and for-loop
|
|
@@ -169,18 +174,18 @@ export class Parser {
|
|
|
169
174
|
parseVarDeclHeader() {
|
|
170
175
|
const start = this.peek();
|
|
171
176
|
const type = this.parseType();
|
|
172
|
-
const
|
|
177
|
+
const nameTok = this.consume(TokenKind.Identifier, "Expected variable name");
|
|
173
178
|
this.consume(TokenKind.Assign, "Expected '=' in variable declaration");
|
|
174
179
|
const init = this.parseExpression();
|
|
175
|
-
return { kind: "VarDecl", isConst: false, name, type, init, line: start.line, col: start.col };
|
|
180
|
+
return { kind: "VarDecl", isConst: false, name: nameTok.lexeme, nameLine: nameTok.line, nameCol: nameTok.col, type, init, line: start.line, col: start.col };
|
|
176
181
|
}
|
|
177
182
|
parseConstDecl() {
|
|
178
183
|
const start = this.advance(); // 'const'
|
|
179
184
|
const type = this.parseType();
|
|
180
|
-
const
|
|
185
|
+
const nameTok = this.consume(TokenKind.Identifier, "Expected constant name");
|
|
181
186
|
this.consume(TokenKind.Assign, "Expected '=' in constant declaration");
|
|
182
187
|
const init = this.parseExpression();
|
|
183
|
-
return { kind: "VarDecl", isConst: true, name, type, init, line: start.line, col: start.col };
|
|
188
|
+
return { kind: "VarDecl", isConst: true, name: nameTok.lexeme, nameLine: nameTok.line, nameCol: nameTok.col, type, init, line: start.line, col: start.col };
|
|
184
189
|
}
|
|
185
190
|
parseParamList() {
|
|
186
191
|
this.consume(TokenKind.LParen, "Expected '('");
|
|
@@ -256,7 +261,8 @@ export class Parser {
|
|
|
256
261
|
}
|
|
257
262
|
const memberStart = this.peek();
|
|
258
263
|
const type = this.parseType();
|
|
259
|
-
const
|
|
264
|
+
const memberNameTok = this.consume(TokenKind.Identifier, "Expected field, property, or method name");
|
|
265
|
+
const memberName = memberNameTok.lexeme;
|
|
260
266
|
if (this.check(TokenKind.LParen)) {
|
|
261
267
|
const params = this.parseParamList();
|
|
262
268
|
const body = this.parseBlock();
|
|
@@ -271,6 +277,8 @@ export class Parser {
|
|
|
271
277
|
isVirtual,
|
|
272
278
|
isOverride,
|
|
273
279
|
name: memberName,
|
|
280
|
+
nameLine: memberNameTok.line,
|
|
281
|
+
nameCol: memberNameTok.col,
|
|
274
282
|
params,
|
|
275
283
|
returnType: type,
|
|
276
284
|
body,
|
|
@@ -303,6 +311,8 @@ export class Parser {
|
|
|
303
311
|
visibility,
|
|
304
312
|
hasSetter,
|
|
305
313
|
name: memberName,
|
|
314
|
+
nameLine: memberNameTok.line,
|
|
315
|
+
nameCol: memberNameTok.col,
|
|
306
316
|
type,
|
|
307
317
|
line: memberStart.line,
|
|
308
318
|
col: memberStart.col,
|
|
@@ -327,6 +337,8 @@ export class Parser {
|
|
|
327
337
|
isStatic,
|
|
328
338
|
initializer,
|
|
329
339
|
name: memberName,
|
|
340
|
+
nameLine: memberNameTok.line,
|
|
341
|
+
nameCol: memberNameTok.col,
|
|
330
342
|
type,
|
|
331
343
|
line: memberStart.line,
|
|
332
344
|
col: memberStart.col,
|
|
@@ -350,10 +362,18 @@ export class Parser {
|
|
|
350
362
|
while (!this.check(TokenKind.RBrace) && !this.check(TokenKind.EOF)) {
|
|
351
363
|
const memberStart = this.peek();
|
|
352
364
|
const returnType = this.parseType();
|
|
353
|
-
const
|
|
365
|
+
const methodNameTok = this.consume(TokenKind.Identifier, "Expected method name");
|
|
354
366
|
const params = this.parseParamList();
|
|
355
367
|
this.consume(TokenKind.Semicolon, "Expected ';' after interface method signature");
|
|
356
|
-
methods.push({
|
|
368
|
+
methods.push({
|
|
369
|
+
name: methodNameTok.lexeme,
|
|
370
|
+
nameLine: methodNameTok.line,
|
|
371
|
+
nameCol: methodNameTok.col,
|
|
372
|
+
params,
|
|
373
|
+
returnType,
|
|
374
|
+
line: memberStart.line,
|
|
375
|
+
col: memberStart.col,
|
|
376
|
+
});
|
|
357
377
|
}
|
|
358
378
|
this.consume(TokenKind.RBrace, "Expected '}' after interface body");
|
|
359
379
|
return { kind: "InterfaceDecl", isExported, name, baseList, methods, line: start.line, col: start.col };
|
|
@@ -405,6 +425,22 @@ export class Parser {
|
|
|
405
425
|
}
|
|
406
426
|
return { modulePath, jsName };
|
|
407
427
|
}
|
|
428
|
+
// `raw string <Name> from "<path>";` — embeds a real file's contents as a
|
|
429
|
+
// JS string constant at compile time. Type must be literally 'string' (no
|
|
430
|
+
// other type makes sense for file contents); no 'as' clause — there's no
|
|
431
|
+
// JS-side name to alias, unlike extern.
|
|
432
|
+
parseRawStringDecl(isExported) {
|
|
433
|
+
const start = this.advance(); // 'raw'
|
|
434
|
+
const typeTok = this.consume(TokenKind.Identifier, "Expected 'string' after 'raw'");
|
|
435
|
+
if (typeTok.lexeme !== "string") {
|
|
436
|
+
this.diagnostics.error(`'raw' declarations must be of type 'string', got '${typeTok.lexeme}'`, typeTok.line, typeTok.col);
|
|
437
|
+
}
|
|
438
|
+
const name = this.consume(TokenKind.Identifier, "Expected name").lexeme;
|
|
439
|
+
this.consume(TokenKind.From, "Expected 'from \"<path>\"' after 'raw string <Name>'");
|
|
440
|
+
const pathTok = this.consume(TokenKind.String, "Expected a file path string after 'from'");
|
|
441
|
+
this.consume(TokenKind.Semicolon, "Expected ';' after 'raw' declaration");
|
|
442
|
+
return { kind: "RawStringDecl", isExported, name, path: pathTok.lexeme, line: start.line, col: start.col };
|
|
443
|
+
}
|
|
408
444
|
parseExternClassBody(start, isExported) {
|
|
409
445
|
const name = this.consume(TokenKind.Identifier, "Expected class name").lexeme;
|
|
410
446
|
this.consume(TokenKind.LBrace, "Expected '{' before extern class body");
|
|
@@ -584,8 +620,8 @@ export class Parser {
|
|
|
584
620
|
type = this.parseFunctionType();
|
|
585
621
|
}
|
|
586
622
|
else if (this.check(TokenKind.Task)) {
|
|
587
|
-
this.advance();
|
|
588
|
-
let resultType = { kind: "NamedType", name: "void" };
|
|
623
|
+
const taskTok = this.advance();
|
|
624
|
+
let resultType = { kind: "NamedType", name: "void", line: taskTok.line, col: taskTok.col };
|
|
589
625
|
if (this.match(TokenKind.Lt)) {
|
|
590
626
|
resultType = this.parseType();
|
|
591
627
|
this.consume(TokenKind.Gt, "Expected '>' after task result type");
|
|
@@ -601,12 +637,21 @@ export class Parser {
|
|
|
601
637
|
}
|
|
602
638
|
else {
|
|
603
639
|
const nameToken = this.check(TokenKind.Void) ? this.advance() : this.consume(TokenKind.Identifier, "Expected type name");
|
|
604
|
-
type = { kind: "NamedType", name: nameToken.lexeme };
|
|
640
|
+
type = { kind: "NamedType", name: nameToken.lexeme, line: nameToken.line, col: nameToken.col };
|
|
605
641
|
}
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
642
|
+
// `[]` and `?` are both postfix and can alternate in either order —
|
|
643
|
+
// `string?[]` (array of nullable strings) and `string[]?` (nullable
|
|
644
|
+
// array of strings) parse with the nesting their order implies.
|
|
645
|
+
while (this.check(TokenKind.LBracket) || this.check(TokenKind.Question)) {
|
|
646
|
+
if (this.check(TokenKind.LBracket)) {
|
|
647
|
+
this.advance();
|
|
648
|
+
this.consume(TokenKind.RBracket, "Expected ']' after '[' in array type");
|
|
649
|
+
type = { kind: "ArrayType", element: type };
|
|
650
|
+
}
|
|
651
|
+
else {
|
|
652
|
+
const q = this.advance();
|
|
653
|
+
type = { kind: "NullableType", inner: type, line: q.line, col: q.col };
|
|
654
|
+
}
|
|
610
655
|
}
|
|
611
656
|
return type;
|
|
612
657
|
}
|
|
@@ -759,6 +804,10 @@ export class Parser {
|
|
|
759
804
|
this.advance();
|
|
760
805
|
return { kind: "BoolLiteral", value: t.kind === TokenKind.True, line: t.line, col: t.col };
|
|
761
806
|
}
|
|
807
|
+
if (this.check(TokenKind.Null)) {
|
|
808
|
+
this.advance();
|
|
809
|
+
return { kind: "NullLiteral", line: t.line, col: t.col };
|
|
810
|
+
}
|
|
762
811
|
if (this.check(TokenKind.This)) {
|
|
763
812
|
this.advance();
|
|
764
813
|
return { kind: "ThisExpr", line: t.line, col: t.col };
|
|
@@ -828,8 +877,18 @@ export class Parser {
|
|
|
828
877
|
if (startKind !== TokenKind.Identifier && startKind !== TokenKind.Void)
|
|
829
878
|
return false;
|
|
830
879
|
i++;
|
|
831
|
-
|
|
832
|
-
|
|
880
|
+
// Mirrors parseType's postfix loop: `[]` and `?` can alternate in
|
|
881
|
+
// either order (`string?[]`, `string[]?`) after the base type name.
|
|
882
|
+
while (true) {
|
|
883
|
+
if (this.tokens[i]?.kind === TokenKind.LBracket && this.tokens[i + 1]?.kind === TokenKind.RBracket) {
|
|
884
|
+
i += 2;
|
|
885
|
+
}
|
|
886
|
+
else if (this.tokens[i]?.kind === TokenKind.Question) {
|
|
887
|
+
i += 1;
|
|
888
|
+
}
|
|
889
|
+
else {
|
|
890
|
+
break;
|
|
891
|
+
}
|
|
833
892
|
}
|
|
834
893
|
return this.tokens[i]?.kind === TokenKind.Identifier;
|
|
835
894
|
}
|
|
@@ -976,6 +1035,7 @@ export class Parser {
|
|
|
976
1035
|
this.check(TokenKind.Interface) ||
|
|
977
1036
|
this.check(TokenKind.Enum) ||
|
|
978
1037
|
this.check(TokenKind.Extern) ||
|
|
1038
|
+
this.check(TokenKind.Raw) ||
|
|
979
1039
|
this.check(TokenKind.Const) ||
|
|
980
1040
|
this.check(TokenKind.If) ||
|
|
981
1041
|
this.check(TokenKind.While) ||
|
package/dist/tokens.js
CHANGED
|
@@ -8,9 +8,11 @@ export var TokenKind;
|
|
|
8
8
|
TokenKind["Identifier"] = "Identifier";
|
|
9
9
|
TokenKind["True"] = "True";
|
|
10
10
|
TokenKind["False"] = "False";
|
|
11
|
+
TokenKind["Null"] = "Null";
|
|
11
12
|
// Keywords
|
|
12
13
|
TokenKind["Using"] = "Using";
|
|
13
14
|
TokenKind["Extern"] = "Extern";
|
|
15
|
+
TokenKind["Raw"] = "Raw";
|
|
14
16
|
TokenKind["From"] = "From";
|
|
15
17
|
TokenKind["As"] = "As";
|
|
16
18
|
TokenKind["Const"] = "Const";
|
|
@@ -61,6 +63,7 @@ export var TokenKind;
|
|
|
61
63
|
TokenKind["Dot"] = "Dot";
|
|
62
64
|
TokenKind["Arrow"] = "Arrow";
|
|
63
65
|
TokenKind["Underscore"] = "Underscore";
|
|
66
|
+
TokenKind["Question"] = "Question";
|
|
64
67
|
// Operators
|
|
65
68
|
TokenKind["Plus"] = "Plus";
|
|
66
69
|
TokenKind["Minus"] = "Minus";
|
package/dist/types.js
CHANGED
|
@@ -24,6 +24,9 @@ export function taskType(resultType) {
|
|
|
24
24
|
export function stateType(valueType) {
|
|
25
25
|
return { kind: "state", valueType };
|
|
26
26
|
}
|
|
27
|
+
export function nullableOf(inner) {
|
|
28
|
+
return inner.kind === "nullable" ? inner : { kind: "nullable", inner };
|
|
29
|
+
}
|
|
27
30
|
export function typeToString(t) {
|
|
28
31
|
switch (t.kind) {
|
|
29
32
|
case "number":
|
|
@@ -44,46 +47,55 @@ export function typeToString(t) {
|
|
|
44
47
|
return t.resultType.kind === "void" ? "task" : `task<${typeToString(t.resultType)}>`;
|
|
45
48
|
case "state":
|
|
46
49
|
return `state<${typeToString(t.valueType)}>`;
|
|
50
|
+
case "nullable":
|
|
51
|
+
return `${typeToString(t.inner)}?`;
|
|
47
52
|
}
|
|
48
53
|
}
|
|
49
54
|
const PRIMITIVE_NAMES = new Set(["number", "string", "bool", "void"]);
|
|
50
55
|
// Resolves a syntactic type annotation to a Type, given the kind of every known
|
|
51
|
-
// user-declared name (class, interface, or enum).
|
|
52
|
-
|
|
56
|
+
// user-declared name (class, interface, or enum). `onNamedType`, when given, is
|
|
57
|
+
// called with every `NamedType` leaf visited and the Type it resolved to — a
|
|
58
|
+
// hook for tools (e.g. hover) that want to know what a type annotation in
|
|
59
|
+
// source actually refers to, without duplicating this resolution logic.
|
|
60
|
+
export function resolveTypeNode(node, namedTypes, onNamedType) {
|
|
53
61
|
if (node.kind === "ArrayType") {
|
|
54
|
-
const element = resolveTypeNode(node.element, namedTypes);
|
|
62
|
+
const element = resolveTypeNode(node.element, namedTypes, onNamedType);
|
|
55
63
|
return element ? arrayOf(element) : null;
|
|
56
64
|
}
|
|
57
65
|
if (node.kind === "FunctionType") {
|
|
58
66
|
const params = [];
|
|
59
67
|
for (const p of node.params) {
|
|
60
|
-
const resolved = resolveTypeNode(p, namedTypes);
|
|
68
|
+
const resolved = resolveTypeNode(p, namedTypes, onNamedType);
|
|
61
69
|
if (!resolved)
|
|
62
70
|
return null;
|
|
63
71
|
params.push(resolved);
|
|
64
72
|
}
|
|
65
|
-
const returnType = resolveTypeNode(node.returnType, namedTypes);
|
|
73
|
+
const returnType = resolveTypeNode(node.returnType, namedTypes, onNamedType);
|
|
66
74
|
return returnType ? functionType(params, returnType) : null;
|
|
67
75
|
}
|
|
68
76
|
if (node.kind === "TaskType") {
|
|
69
|
-
const resultType = resolveTypeNode(node.resultType, namedTypes);
|
|
77
|
+
const resultType = resolveTypeNode(node.resultType, namedTypes, onNamedType);
|
|
70
78
|
return resultType ? taskType(resultType) : null;
|
|
71
79
|
}
|
|
72
80
|
if (node.kind === "StateType") {
|
|
73
|
-
const valueType = resolveTypeNode(node.valueType, namedTypes);
|
|
81
|
+
const valueType = resolveTypeNode(node.valueType, namedTypes, onNamedType);
|
|
74
82
|
return valueType ? stateType(valueType) : null;
|
|
75
83
|
}
|
|
84
|
+
if (node.kind === "NullableType") {
|
|
85
|
+
const inner = resolveTypeNode(node.inner, namedTypes, onNamedType);
|
|
86
|
+
return inner ? nullableOf(inner) : null;
|
|
87
|
+
}
|
|
88
|
+
let resolved;
|
|
76
89
|
if (PRIMITIVE_NAMES.has(node.name)) {
|
|
77
|
-
|
|
90
|
+
resolved = { kind: node.name };
|
|
78
91
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
return null;
|
|
92
|
+
else {
|
|
93
|
+
const kind = namedTypes.get(node.name);
|
|
94
|
+
resolved = kind === "class" ? classType(node.name) : kind === "interface" ? interfaceType(node.name) : kind === "enum" ? enumType(node.name) : null;
|
|
95
|
+
}
|
|
96
|
+
if (resolved)
|
|
97
|
+
onNamedType?.(node, resolved);
|
|
98
|
+
return resolved;
|
|
87
99
|
}
|
|
88
100
|
export function typesEqual(a, b) {
|
|
89
101
|
if (a.kind === "unknown" || b.kind === "unknown")
|
|
@@ -101,6 +113,9 @@ export function typesEqual(a, b) {
|
|
|
101
113
|
if (a.kind === "state" && b.kind === "state") {
|
|
102
114
|
return typesEqual(a.valueType, b.valueType);
|
|
103
115
|
}
|
|
116
|
+
if (a.kind === "nullable" && b.kind === "nullable") {
|
|
117
|
+
return typesEqual(a.inner, b.inner);
|
|
118
|
+
}
|
|
104
119
|
if ((a.kind === "class" || a.kind === "interface" || a.kind === "enum") && "name" in b) {
|
|
105
120
|
return a.name === b.name;
|
|
106
121
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kopscript",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "KopScript: a small OOP, strongly-typed language that transpiles to JavaScript",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -19,7 +19,9 @@
|
|
|
19
19
|
"main": "./dist/modules.js",
|
|
20
20
|
"files": [
|
|
21
21
|
"dist",
|
|
22
|
-
"bin"
|
|
22
|
+
"bin",
|
|
23
|
+
"assets",
|
|
24
|
+
"LLM.md"
|
|
23
25
|
],
|
|
24
26
|
"bin": {
|
|
25
27
|
"ks": "bin/ks.js"
|